From 9a2a3c3dcc0ecaf8b9a60d7a054c2afe1564bb7a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 14:08:21 +0000 Subject: [PATCH 01/27] Bump com.google.protobuf:protobuf-java from 4.27.2 to 4.28.0 Bumps [com.google.protobuf:protobuf-java](https://github.com/protocolbuffers/protobuf) from 4.27.2 to 4.28.0. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/protobuf_release.bzl) - [Commits](https://github.com/protocolbuffers/protobuf/commits) --- updated-dependencies: - dependency-name: com.google.protobuf:protobuf-java dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- contribs/hybridsim/pom.xml | 2 +- contribs/protobuf/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contribs/hybridsim/pom.xml b/contribs/hybridsim/pom.xml index f58a572c939..b480aa197dd 100644 --- a/contribs/hybridsim/pom.xml +++ b/contribs/hybridsim/pom.xml @@ -10,7 +10,7 @@ hybridsim - 4.27.2 + 4.28.0 1.65.1 diff --git a/contribs/protobuf/pom.xml b/contribs/protobuf/pom.xml index a2c8a4ef62b..a08c2d527c8 100644 --- a/contribs/protobuf/pom.xml +++ b/contribs/protobuf/pom.xml @@ -11,7 +11,7 @@ protobuf - 4.27.2 + 4.28.0 From 544999918b1d4023cd857e91ca7af95b81109ea7 Mon Sep 17 00:00:00 2001 From: Tarek Chouaki Date: Wed, 4 Sep 2024 17:24:34 +0200 Subject: [PATCH 02/27] feat: DiscreteModeChoiceModule write utilities as an output. --- .../modules/DiscreteModeChoiceModule.java | 1 + .../modules/UtilitiesWriterHandler.java | 52 ++++++ .../config/DiscreteModeChoiceConfigGroup.java | 25 ++- .../DiscreteModeChoiceAlgorithm.java | 152 +++++++++--------- 4 files changed, 153 insertions(+), 77 deletions(-) create mode 100644 contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/modules/UtilitiesWriterHandler.java 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 abf34cb42f6..c669cc0d237 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 @@ -23,6 +23,7 @@ public class DiscreteModeChoiceModule extends AbstractModule { @Override public void install() { addPlanStrategyBinding(STRATEGY_NAME).toProvider(DiscreteModeChoiceStrategyProvider.class); + addControlerListenerBinding().to(UtilitiesWriterHandler.class); 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/UtilitiesWriterHandler.java b/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/modules/UtilitiesWriterHandler.java new file mode 100644 index 00000000000..ff89cfcdc35 --- /dev/null +++ b/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/modules/UtilitiesWriterHandler.java @@ -0,0 +1,52 @@ +package org.matsim.contribs.discrete_mode_choice.modules; + +import com.google.inject.Inject; +import org.matsim.api.core.v01.population.Population; +import org.matsim.contribs.discrete_mode_choice.modules.config.DiscreteModeChoiceConfigGroup; +import org.matsim.contribs.discrete_mode_choice.modules.utils.ExtractPlanUtilities; +import org.matsim.core.config.groups.ControllerConfigGroup; +import org.matsim.core.controler.OutputDirectoryHierarchy; +import org.matsim.core.controler.events.IterationStartsEvent; +import org.matsim.core.controler.events.ShutdownEvent; +import org.matsim.core.controler.listener.IterationStartsListener; +import org.matsim.core.controler.listener.ShutdownListener; + +import java.io.IOException; + +public class UtilitiesWriterHandler implements ShutdownListener, IterationStartsListener { + private final OutputDirectoryHierarchy outputDirectoryHierarchy; + private final ControllerConfigGroup controllerConfigGroup; + private final Population population; + private final DiscreteModeChoiceConfigGroup discreteModeChoiceConfigGroup; + + @Inject + public UtilitiesWriterHandler(ControllerConfigGroup controllerConfigGroup, DiscreteModeChoiceConfigGroup discreteModeChoiceConfigGroup, Population population, OutputDirectoryHierarchy outputDirectoryHierarchy) { + this.controllerConfigGroup = controllerConfigGroup; + this.discreteModeChoiceConfigGroup = discreteModeChoiceConfigGroup; + this.population = population; + this.outputDirectoryHierarchy = outputDirectoryHierarchy; + } + + @Override + public void notifyShutdown(ShutdownEvent event) { + String filePath = this.outputDirectoryHierarchy.getOutputFilename("dmc_utilities.csv"); + try { + ExtractPlanUtilities.writePlanUtilities(population, filePath); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public void notifyIterationStarts(IterationStartsEvent event) { + if(event.getIteration() == controllerConfigGroup.getFirstIteration() || this.discreteModeChoiceConfigGroup.getWriteUtilitiesInterval() % event.getIteration() != 0) { + return; + } + String filePath = this.outputDirectoryHierarchy.getIterationFilename(event.getIteration(), "dmc_utilities.csv"); + try { + ExtractPlanUtilities.writePlanUtilities(population, filePath); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/modules/config/DiscreteModeChoiceConfigGroup.java b/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/modules/config/DiscreteModeChoiceConfigGroup.java index c692de9d40b..f85779aed35 100644 --- a/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/modules/config/DiscreteModeChoiceConfigGroup.java +++ b/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/modules/config/DiscreteModeChoiceConfigGroup.java @@ -8,6 +8,7 @@ import java.util.Map; import java.util.stream.Collectors; +import jakarta.validation.constraints.Positive; import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceModel; import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceModel.FallbackBehaviour; import org.matsim.contribs.discrete_mode_choice.modules.ConstraintModule; @@ -27,7 +28,7 @@ /** * Main config group for the DiscreteModeChoice extension. - * + * * @author sebhoerl */ public class DiscreteModeChoiceConfigGroup extends ReflectiveConfigGroup { @@ -53,7 +54,8 @@ public class DiscreteModeChoiceConfigGroup extends ReflectiveConfigGroup { private Collection tripFilters = new HashSet<>(); private Collection cachedModes = new HashSet<>(); - + @Positive + private int writeUtilitiesInterval = 0; public static final String GROUP_NAME = "DiscreteModeChoice"; public static final String PERFORM_REROUTE = "performReroute"; @@ -110,6 +112,9 @@ public class DiscreteModeChoiceConfigGroup extends ReflectiveConfigGroup { public static final String CACHED_MODES = "cachedModes"; public static final String CACHED_MODES_CMT = "Trips tested with the modes listed here will be cached for each combination of trip and agent during one replanning pass."; + public static final String WRITE_UTILITIES_INTERVAL = "writeUtilitiesInterval"; + public static final String WRITE_UTILITIES_INTERVAL_CMT = "Specifies the interval, in iterations, at which the dmc_utilities.csv file is written. If set to 0, the file is written only at the end of the simulation"; + public DiscreteModeChoiceConfigGroup() { super(GROUP_NAME); } @@ -436,6 +441,22 @@ public String getCachedModesAsString() { return String.join(", ", cachedModes); } + /** + * @param writeUtilitiesInterval -- {@value #WRITE_UTILITIES_INTERVAL_CMT} + */ + @StringSetter(WRITE_UTILITIES_INTERVAL) + public void setWriteUtilitiesInterval(int writeUtilitiesInterval) { + this.writeUtilitiesInterval = writeUtilitiesInterval; + } + + /** + * @return -- {@value #WRITE_UTILITIES_INTERVAL_CMT} + */ + @StringGetter(WRITE_UTILITIES_INTERVAL) + public int getWriteUtilitiesInterval() { + return this.writeUtilitiesInterval; + } + // --- Component configuration --- private final Map, ConfigGroup> componentRegistry = createComponentRegistry( diff --git a/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/replanning/DiscreteModeChoiceAlgorithm.java b/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/replanning/DiscreteModeChoiceAlgorithm.java index 655f3cd94a6..a4c10c02d7a 100644 --- a/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/replanning/DiscreteModeChoiceAlgorithm.java +++ b/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/replanning/DiscreteModeChoiceAlgorithm.java @@ -1,75 +1,77 @@ -package org.matsim.contribs.discrete_mode_choice.replanning; - -import java.util.Collections; -import java.util.List; -import java.util.Random; - -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.api.core.v01.population.PopulationFactory; -import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceModel; -import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceTrip; -import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceModel.NoFeasibleChoiceException; -import org.matsim.contribs.discrete_mode_choice.model.trip_based.candidates.RoutedTripCandidate; -import org.matsim.contribs.discrete_mode_choice.model.trip_based.candidates.TripCandidate; -import org.matsim.core.population.algorithms.PlanAlgorithm; -import org.matsim.core.router.TripRouter; - -/** - * This replanning algorithm uses a predefined discrete mode choice model to - * perform mode decisions for a given plan. - * - * @author sebhoerl - */ -public class DiscreteModeChoiceAlgorithm implements PlanAlgorithm { - private final Random random; - private final DiscreteModeChoiceModel modeChoiceModel; - private final TripListConverter tripListConverter; - - private final PopulationFactory populationFactory; - - public DiscreteModeChoiceAlgorithm(Random random, DiscreteModeChoiceModel modeChoiceModel, - PopulationFactory populationFactory, TripListConverter tripListConverter) { - this.random = random; - this.modeChoiceModel = modeChoiceModel; - this.populationFactory = populationFactory; - this.tripListConverter = tripListConverter; - } - - @Override - /** - * Performs mode choice on a plan. We assume that TripsToLegs has been called - * before, hence the code is working diretly on legs. - */ - public void run(Plan plan) { - // I) First build a list of DiscreteModeChoiceTrips - List trips = tripListConverter.convert(plan); - - // II) Run mode choice - - try { - // Perform mode choice and retrieve candidates - List chosenCandidates = modeChoiceModel.chooseModes(plan.getPerson(), trips, random); - - for (int i = 0; i < trips.size(); i++) { - DiscreteModeChoiceTrip trip = trips.get(i); - TripCandidate candidate = chosenCandidates.get(i); - - List insertElements; - - if (candidate instanceof RoutedTripCandidate) { - RoutedTripCandidate routedCandidate = (RoutedTripCandidate) candidate; - insertElements = routedCandidate.getRoutedPlanElements(); - } else { - Leg insertLeg = populationFactory.createLeg(candidate.getMode()); - insertElements = Collections.singletonList(insertLeg); - } - - TripRouter.insertTrip(plan, trip.getOriginActivity(), insertElements, trip.getDestinationActivity()); - } - } catch (NoFeasibleChoiceException e) { - throw new IllegalStateException(e); - } - } -} +package org.matsim.contribs.discrete_mode_choice.replanning; + +import java.util.Collections; +import java.util.List; +import java.util.Random; + +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.api.core.v01.population.PopulationFactory; +import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceModel; +import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceTrip; +import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceModel.NoFeasibleChoiceException; +import org.matsim.contribs.discrete_mode_choice.model.trip_based.candidates.RoutedTripCandidate; +import org.matsim.contribs.discrete_mode_choice.model.trip_based.candidates.TripCandidate; +import org.matsim.contribs.discrete_mode_choice.model.utilities.UtilityCandidate; +import org.matsim.core.population.algorithms.PlanAlgorithm; +import org.matsim.core.router.TripRouter; + +/** + * This replanning algorithm uses a predefined discrete mode choice model to + * perform mode decisions for a given plan. + * + * @author sebhoerl + */ +public class DiscreteModeChoiceAlgorithm implements PlanAlgorithm { + private final Random random; + private final DiscreteModeChoiceModel modeChoiceModel; + private final TripListConverter tripListConverter; + + private final PopulationFactory populationFactory; + + public DiscreteModeChoiceAlgorithm(Random random, DiscreteModeChoiceModel modeChoiceModel, + PopulationFactory populationFactory, TripListConverter tripListConverter) { + this.random = random; + this.modeChoiceModel = modeChoiceModel; + this.populationFactory = populationFactory; + this.tripListConverter = tripListConverter; + } + + @Override + /** + * Performs mode choice on a plan. We assume that TripsToLegs has been called + * before, hence the code is working diretly on legs. + */ + public void run(Plan plan) { + // I) First build a list of DiscreteModeChoiceTrips + List trips = tripListConverter.convert(plan); + + // II) Run mode choice + + try { + // Perform mode choice and retrieve candidates + List chosenCandidates = modeChoiceModel.chooseModes(plan.getPerson(), trips, random); + + for (int i = 0; i < trips.size(); i++) { + DiscreteModeChoiceTrip trip = trips.get(i); + TripCandidate candidate = chosenCandidates.get(i); + + List insertElements; + + if (candidate instanceof RoutedTripCandidate) { + RoutedTripCandidate routedCandidate = (RoutedTripCandidate) candidate; + insertElements = routedCandidate.getRoutedPlanElements(); + } else { + Leg insertLeg = populationFactory.createLeg(candidate.getMode()); + insertElements = Collections.singletonList(insertLeg); + } + + TripRouter.insertTrip(plan, trip.getOriginActivity(), insertElements, trip.getDestinationActivity()); + } + plan.getAttributes().putAttribute("utility", chosenCandidates.stream().mapToDouble(UtilityCandidate::getUtility).sum()); + } catch (NoFeasibleChoiceException e) { + throw new IllegalStateException(e); + } + } +} From 2a67490362bc290ce02a1bcd5cdbe5fdc140e583 Mon Sep 17 00:00:00 2001 From: Tarek Chouaki Date: Wed, 4 Sep 2024 17:45:01 +0200 Subject: [PATCH 03/27] fix: add missing ExtractPlanUtilities class --- .../modules/utils/ExtractPlanUtilities.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/modules/utils/ExtractPlanUtilities.java diff --git a/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/modules/utils/ExtractPlanUtilities.java b/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/modules/utils/ExtractPlanUtilities.java new file mode 100644 index 00000000000..d68b7176728 --- /dev/null +++ b/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/modules/utils/ExtractPlanUtilities.java @@ -0,0 +1,51 @@ +package org.matsim.contribs.discrete_mode_choice.modules.utils; + +import org.matsim.api.core.v01.Scenario; +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.core.config.CommandLine; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigUtils; +import org.matsim.core.population.io.PopulationReader; +import org.matsim.core.scenario.ScenarioUtils; + +import java.io.FileWriter; +import java.io.IOException; + +public class ExtractPlanUtilities { + public static void writePlanUtilities(Population population, String filePath) throws IOException { + FileWriter writer = new FileWriter(filePath); + writer.write(String.join(CSV_SEPARATOR, CSV_HEADER)); + writer.write("\n"); + + for(Person person: population.getPersons().values()) { + double utility = Double.NaN; + Plan plan = person.getSelectedPlan(); + if(plan != null && plan.getAttributes().getAttribute("utility") != null) { + utility = (double) plan.getAttributes().getAttribute("utility"); + } + writer.write(String.join(CSV_SEPARATOR, new String[]{ + person.getId().toString(), + String.valueOf(utility) + })); + writer.write("\n"); + } + writer.close(); + } + + public static final String CMD_PLANS_PATH = "plans-path"; + public static final String CMD_OUTPUT_PATH = "output-path"; + public static final String CSV_SEPARATOR = ";"; + public static final String[] CSV_HEADER = new String[]{"person_id", "utility"}; + + public static void main(String[] args) throws CommandLine.ConfigurationException, IOException { + CommandLine commandLine = new CommandLine.Builder(args).requireOptions(CMD_PLANS_PATH, CMD_OUTPUT_PATH).build(); + + Config config = ConfigUtils.createConfig(); + Scenario scenario = ScenarioUtils.createScenario(config); + new PopulationReader(scenario).readFile(commandLine.getOptionStrict(CMD_PLANS_PATH)); + + writePlanUtilities(scenario.getPopulation(), commandLine.getOptionStrict(CMD_OUTPUT_PATH)); + } +} From e9b8fd5c577e360dcae62b079e488dd8d5fa0142 Mon Sep 17 00:00:00 2001 From: Tarek Chouaki Date: Wed, 4 Sep 2024 18:05:58 +0200 Subject: [PATCH 04/27] fix: default value of writeUtilitiesInterval --- .../modules/config/DiscreteModeChoiceConfigGroup.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/modules/config/DiscreteModeChoiceConfigGroup.java b/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/modules/config/DiscreteModeChoiceConfigGroup.java index f85779aed35..5a437d97b22 100644 --- a/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/modules/config/DiscreteModeChoiceConfigGroup.java +++ b/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/modules/config/DiscreteModeChoiceConfigGroup.java @@ -55,7 +55,7 @@ public class DiscreteModeChoiceConfigGroup extends ReflectiveConfigGroup { private Collection cachedModes = new HashSet<>(); @Positive - private int writeUtilitiesInterval = 0; + private int writeUtilitiesInterval = 1; public static final String GROUP_NAME = "DiscreteModeChoice"; public static final String PERFORM_REROUTE = "performReroute"; From 87a6887c30294c763422f2673a3fd5f4b3cc5dcc Mon Sep 17 00:00:00 2001 From: nkuehnel Date: Fri, 6 Sep 2024 00:53:14 +0200 Subject: [PATCH 05/27] drt: allow final stay task without requests in preplanned scenarios --- .../optimizer/PreplannedDrtOptimizer.java | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) 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 5dd5f1c8bf7..fd0f6672826 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 @@ -174,17 +174,22 @@ public void nextTask(DvrpVehicle vehicle) { } else { nonVisitedPreplannedStops.poll();//remove this stop from queue - var stopTask = taskFactory.createStopTask(vehicle, currentTime, currentTime + stopDuration, currentLink); - if (nextStop.pickup) { - var request = Preconditions.checkNotNull(openRequests.get(nextStop.preplannedRequest.key), - "Request (%s) has not been yet submitted", nextStop.preplannedRequest); - stopTask.addPickupRequest(AcceptedDrtRequest.createFromOriginalRequest(request)); + if(nextStop.preplannedRequest.key.passengerIds.isEmpty() && nonVisitedPreplannedStops.isEmpty()) { + var stayTask = taskFactory.createStayTask(vehicle, currentTime, vehicle.getServiceEndTime(), currentLink); + schedule.addTask(stayTask); } else { - var request = Preconditions.checkNotNull(openRequests.remove(nextStop.preplannedRequest.key), - "Request (%s) has not been yet submitted", nextStop.preplannedRequest); - stopTask.addDropoffRequest(AcceptedDrtRequest.createFromOriginalRequest(request)); + var stopTask = taskFactory.createStopTask(vehicle, currentTime, currentTime + stopDuration, currentLink); + if (nextStop.pickup) { + var request = Preconditions.checkNotNull(openRequests.get(nextStop.preplannedRequest.key), + "Request (%s) has not been yet submitted", nextStop.preplannedRequest); + stopTask.addPickupRequest(AcceptedDrtRequest.createFromOriginalRequest(request)); + } else { + var request = Preconditions.checkNotNull(openRequests.remove(nextStop.preplannedRequest.key), + "Request (%s) has not been yet submitted", nextStop.preplannedRequest); + stopTask.addDropoffRequest(AcceptedDrtRequest.createFromOriginalRequest(request)); + } + schedule.addTask(stopTask); } - schedule.addTask(stopTask); } // switch to the next task and update currentTasks From 7a5b1624df95242bd8896bd44c04fc3dc21d7f50 Mon Sep 17 00:00:00 2001 From: Tobias Kohl Date: Wed, 4 Sep 2024 16:31:27 +0200 Subject: [PATCH 06/27] fix parking proxy bug --- .../parkingproxy/CarEgressWalkChanger.java | 102 ++++++++++++------ .../parkingproxy/ParkingProxyModule.java | 4 +- 2 files changed, 72 insertions(+), 34 deletions(-) diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingproxy/CarEgressWalkChanger.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingproxy/CarEgressWalkChanger.java index ee231f716ed..20c0b113bed 100644 --- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingproxy/CarEgressWalkChanger.java +++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingproxy/CarEgressWalkChanger.java @@ -33,7 +33,7 @@ *

* This class allows to implicitly apply penalties to plans by changing the duration of the egress walk after car interactions. * By construction this only works for plans involving car trips and can not be used if you want to penalize all plans that - * fulfill a certain condition. + * fulfill a certain condition. Note that if you bind this, you should also bind the return value of {@link #getBackChanger()}! *

*

* More precisely, the class will...
@@ -49,13 +49,14 @@ * @author tkohl / Senozon * */ -class CarEgressWalkChanger implements BeforeMobsimListener, AfterMobsimListener { +class CarEgressWalkChanger implements BeforeMobsimListener { public static final String PENALTY_ATTRIBUTE = "parkingPenalty"; private final CarEgressWalkObserver observer; private final AccessEgressFinder egressFinder = new AccessEgressFinder(TransportMode.car); private final Iter0Method iter0Method; + private final CarEgressWalkBackChanger backChanger; /** * Sets the class up with the specified {@linkplain PenaltyGenerator} and {@linkplain PenaltyFunction}. @@ -66,6 +67,21 @@ class CarEgressWalkChanger implements BeforeMobsimListener, AfterMobsimListener public CarEgressWalkChanger(PenaltyGenerator penaltyGenerator, PenaltyFunction penaltyFunction, CarEgressWalkObserver observer, Iter0Method iter0Method) { this.observer = observer; this.iter0Method = iter0Method; + this.backChanger = new CarEgressWalkBackChanger(this); + } + + @Override + public double priority() { //we want this to happen very late, because it should only affect the mobsim, not other listeners + return -1001; + } + + /** + * Returns the class that changes the egress walks bag in AfterMobsim. Note that you need to bind this separately! + * + * @return the {@linkplain CarEgressWalkBackChanger} to this class + */ + public CarEgressWalkBackChanger getBackChanger() { + return this.backChanger; } /** @@ -93,33 +109,6 @@ public void notifyBeforeMobsim(BeforeMobsimEvent event) { this.changeEgressTimesByGridcell(event.getServices().getScenario().getPopulation().getPersons().values(), false); } } - - /** - * resets egress times before scoring / replanning - */ - @Override - public void notifyAfterMobsim(AfterMobsimEvent event) { - // we need to roll back the changes we made before the mobsim, otherwise we can't apply - // a different penalty next iteration. - if (event.getIteration() == 0) { - switch (this.iter0Method) { - case noPenalty: - case hourPenalty: - case estimateFromPlans: - this.changeEgressTimesByGridcell(event.getServices().getScenario().getPopulation().getPersons().values(), true); - break; - case takeFromAttributes: - this.changeEgressTimesByAttribute(event.getServices().getScenario().getPopulation().getPersons().values(), true); - break; - default: - throw new RuntimeException("Unknown iter0 mode"); - } - } else { - this.changeEgressTimesByGridcell(event.getServices().getScenario().getPopulation().getPersons().values(), true); - } - // yyyy this is something we do not like: to just "fake" something and take it back afterwards. Would be good to find some other design - // eventually. Not so obvious, though ... kai, mar'20 - } /** * Changes the egress times of all agents using cars according to the penalty for the corresponding space-time-gridcell and writes the penalty @@ -130,12 +119,13 @@ public void notifyAfterMobsim(AfterMobsimEvent event) { * by that time (calling this method twice, first with {@code false}, then with {@code true} should yield the original plans) */ private void changeEgressTimesByGridcell(Collection population, boolean reverse) { - int sign = reverse ? -1 : 1; for (Person p : population) { for (LegActPair walkActPair : this.egressFinder.findEgressWalks(p.getSelectedPlan())) { - double penalty = sign * this.observer.getPenaltyCalculator().getPenalty(walkActPair.leg.getDepartureTime().seconds(), walkActPair.act.getCoord()); - setTimes(walkActPair, penalty); - if (!reverse) { + double penalty = Math.round(this.observer.getPenaltyCalculator().getPenalty(walkActPair.leg.getDepartureTime().seconds(), walkActPair.act.getCoord())); + if (reverse) { + setTimes(walkActPair, -penalty); + } else { + setTimes(walkActPair, penalty); walkActPair.leg.getAttributes().putAttribute(PENALTY_ATTRIBUTE, penalty); } } @@ -171,4 +161,50 @@ private static void setTimes(LegActPair walkActPair, double penalty) { walkActPair.leg.getRoute().setTravelTime(walkActPair.leg.getRoute().getTravelTime().seconds() + penalty); walkActPair.act.setStartTime(walkActPair.act.getStartTime().seconds() + penalty); } + + /** + * The reverse to {@linkplain CarEgressWalkChanger} + * + * @author tkohl + * + */ + static class CarEgressWalkBackChanger implements AfterMobsimListener { + private final CarEgressWalkChanger forwardChanger; + + CarEgressWalkBackChanger(CarEgressWalkChanger forwardChanger) { + this.forwardChanger = forwardChanger; + } + + @Override + public double priority() { //we want this to happen very early to undo what we did before the mobsim before other listeners can pick it up + return 1001; + } + + /** + * resets egress times before scoring / replanning + */ + @Override + public void notifyAfterMobsim(AfterMobsimEvent event) { + // we need to roll back the changes we made before the mobsim, otherwise we can't apply + // a different penalty next iteration. + if (event.getIteration() == 0) { + switch (forwardChanger.iter0Method) { + case noPenalty: + case hourPenalty: + case estimateFromPlans: + forwardChanger.changeEgressTimesByGridcell(event.getServices().getScenario().getPopulation().getPersons().values(), true); + break; + case takeFromAttributes: + forwardChanger.changeEgressTimesByAttribute(event.getServices().getScenario().getPopulation().getPersons().values(), true); + break; + default: + throw new RuntimeException("Unknown iter0 mode"); + } + } else { + forwardChanger.changeEgressTimesByGridcell(event.getServices().getScenario().getPopulation().getPersons().values(), true); + } + // yyyy this is something we do not like: to just "fake" something and take it back afterwards. Would be good to find some other design + // eventually. Not so obvious, though ... kai, mar'20 + } + } } diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingproxy/ParkingProxyModule.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingproxy/ParkingProxyModule.java index f356f0911e8..41f179d4977 100644 --- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingproxy/ParkingProxyModule.java +++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingproxy/ParkingProxyModule.java @@ -92,7 +92,9 @@ public void install() { if (parkingConfig.getObserveOnly()) { super.addControlerListenerBinding().toInstance(walkObserver); } else { - super.addControlerListenerBinding().toInstance(new CarEgressWalkChanger(parkingHandler, penaltyFunction, walkObserver, parkingConfig.getIter0Method())); + CarEgressWalkChanger walkChanger = new CarEgressWalkChanger(parkingHandler, penaltyFunction, walkObserver, parkingConfig.getIter0Method()); + super.addControlerListenerBinding().toInstance(walkChanger); + super.addControlerListenerBinding().toInstance(walkChanger.getBackChanger()); } } From 5b413100845da75c56c609744fa081c9c6760aa1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Sep 2024 08:51:29 +0000 Subject: [PATCH 07/27] Bump org.apache.commons:commons-lang3 from 3.14.0 to 3.17.0 Bumps org.apache.commons:commons-lang3 from 3.14.0 to 3.17.0. --- updated-dependencies: - dependency-name: org.apache.commons:commons-lang3 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f7866d67c0a..e4c634b092e 100644 --- a/pom.xml +++ b/pom.xml @@ -108,7 +108,7 @@ org.apache.commons commons-lang3 - 3.14.0 + 3.17.0 org.apache.commons From ba0cfdba7378232eefb17f3aaecf68b9ffd702ed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Sep 2024 09:49:51 +0000 Subject: [PATCH 08/27] Bump org.locationtech.jts:jts-core from 1.19.0 to 1.20.0 Bumps org.locationtech.jts:jts-core from 1.19.0 to 1.20.0. --- updated-dependencies: - dependency-name: org.locationtech.jts:jts-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e4c634b092e..f6b0c357d19 100644 --- a/pom.xml +++ b/pom.xml @@ -33,7 +33,7 @@ 2.23.1 31.3 0.49.2 - 1.19.0 + 1.20.0 7.0.0 2.17.2 2.5.0 From 5957b1f625de36712774ab890009600d5528c5e3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Sep 2024 10:27:40 +0000 Subject: [PATCH 09/27] Bump com.github.luben:zstd-jni from 1.5.6-3 to 1.5.6-5 Bumps [com.github.luben:zstd-jni](https://github.com/luben/zstd-jni) from 1.5.6-3 to 1.5.6-5. - [Commits](https://github.com/luben/zstd-jni/compare/v1.5.6-3...v1.5.6-5) --- updated-dependencies: - dependency-name: com.github.luben:zstd-jni dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- matsim/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matsim/pom.xml b/matsim/pom.xml index 7f768fffe76..e5c689b9261 100644 --- a/matsim/pom.xml +++ b/matsim/pom.xml @@ -222,7 +222,7 @@ com.github.luben zstd-jni - 1.5.6-3 + 1.5.6-5 jakarta.validation From 494491dce749247ee165f0ad382e6689ef020047 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Sep 2024 10:28:20 +0000 Subject: [PATCH 10/27] Bump org.slf4j:slf4j-api from 2.0.13 to 2.0.16 Bumps org.slf4j:slf4j-api from 2.0.13 to 2.0.16. --- updated-dependencies: - dependency-name: org.slf4j:slf4j-api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f6b0c357d19..58c7d09aaf5 100644 --- a/pom.xml +++ b/pom.xml @@ -242,7 +242,7 @@ org.slf4j slf4j-api - 2.0.13 + 2.0.16 From 5780cf4c0ff1c859ef7b81d21582b6ac99d8e7aa Mon Sep 17 00:00:00 2001 From: rakow Date: Fri, 6 Sep 2024 13:45:10 +0200 Subject: [PATCH 11/27] use correct transit modes in pt pseudo network (#3453) --- .../src/main/java/org/matsim/pt/utils/CreatePseudoNetwork.java | 1 + 1 file changed, 1 insertion(+) diff --git a/matsim/src/main/java/org/matsim/pt/utils/CreatePseudoNetwork.java b/matsim/src/main/java/org/matsim/pt/utils/CreatePseudoNetwork.java index e2d6ff5078c..30ab02ad413 100644 --- a/matsim/src/main/java/org/matsim/pt/utils/CreatePseudoNetwork.java +++ b/matsim/src/main/java/org/matsim/pt/utils/CreatePseudoNetwork.java @@ -120,6 +120,7 @@ private void createStopNodesAndLoopLinks() { this.nodes.put(stop, node); Link loopLink = this.network.getFactory().createLink(Id.createLinkId (this.prefix + stop.getId()), node, node); + loopLink.setAllowedModes(this.transitModes); stop.setLinkId(loopLink.getId()); this.network.addLink(loopLink); Tuple connection = new Tuple<>(node, node); From 346290a2716a3fd40914167412e8cfb02e3ed9b7 Mon Sep 17 00:00:00 2001 From: Chengqi Lu <43133404+luchengqi7@users.noreply.github.com> Date: Fri, 6 Sep 2024 20:35:25 +0200 Subject: [PATCH 12/27] Adding geometry-free zone-system (#3423) * Add geometry free zone system basics * Add network preparation for geometry-free zonal system * Update pom.xml * update the zone generation script * Update PrepareMaxTravelTimeBasedZonalSystem.java --- contribs/application/pom.xml | 10 +- .../MaxTravelTimeBasedZoneGenerator.java | 407 ++++++++++++++++++ .../PrepareMaxTravelTimeBasedZonalSystem.java | 110 +++++ .../zone_preparation/ProgressPrinter.java | 52 +++ contribs/common/pom.xml | 2 +- .../contrib/common/zones/ZoneSystemUtils.java | 5 +- .../GeometryFreeZoneSystem.java | 61 +++ .../GeometryFreeZoneSystemParams.java | 32 ++ .../analysis/zonal/DrtZoneSystemParams.java | 8 + .../skims/DvrpTravelTimeMatrixParams.java | 5 + 10 files changed, 688 insertions(+), 4 deletions(-) create mode 100644 contribs/application/src/main/java/org/matsim/application/prepare/network/zone_preparation/MaxTravelTimeBasedZoneGenerator.java create mode 100644 contribs/application/src/main/java/org/matsim/application/prepare/network/zone_preparation/PrepareMaxTravelTimeBasedZonalSystem.java create mode 100644 contribs/application/src/main/java/org/matsim/application/prepare/network/zone_preparation/ProgressPrinter.java create mode 100644 contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/geom_free_zones/GeometryFreeZoneSystem.java create mode 100644 contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/geom_free_zones/GeometryFreeZoneSystemParams.java diff --git a/contribs/application/pom.xml b/contribs/application/pom.xml index 4035f096a83..0ac05d56158 100644 --- a/contribs/application/pom.xml +++ b/contribs/application/pom.xml @@ -148,8 +148,14 @@ xercesImpl 2.12.2 - - + + org.matsim.contrib + dvrp + 2025.0-SNAPSHOT + compile + + + diff --git a/contribs/application/src/main/java/org/matsim/application/prepare/network/zone_preparation/MaxTravelTimeBasedZoneGenerator.java b/contribs/application/src/main/java/org/matsim/application/prepare/network/zone_preparation/MaxTravelTimeBasedZoneGenerator.java new file mode 100644 index 00000000000..bbbacc6bdb7 --- /dev/null +++ b/contribs/application/src/main/java/org/matsim/application/prepare/network/zone_preparation/MaxTravelTimeBasedZoneGenerator.java @@ -0,0 +1,407 @@ +package org.matsim.application.prepare.network.zone_preparation; + +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.network.Node; +import org.matsim.contrib.dvrp.router.TimeAsTravelDisutility; +import org.matsim.contrib.dvrp.trafficmonitoring.QSimFreeSpeedTravelTime; +import org.matsim.contrib.zone.skims.SparseMatrix; +import org.matsim.contrib.zone.skims.TravelTimeMatrices; +import org.matsim.core.router.util.TravelDisutility; +import org.matsim.core.router.util.TravelTime; + +import java.util.*; + +public class MaxTravelTimeBasedZoneGenerator { + private final Network network; + private final double timeRadius; + private final Map, Set>> reachableLinksMap = new HashMap<>(); + private final SparseMatrix freeSpeedTravelTimeSparseMatrix; + private final Set> linksTobeCovered = new HashSet<>(); + private final int zoneGenerationIterations; + private final Map, List> zonalSystemData = new LinkedHashMap<>(); + + private static final Logger log = LogManager.getLogger(MaxTravelTimeBasedZoneGenerator.class); + + public MaxTravelTimeBasedZoneGenerator(Network network, double timeRadius, + SparseMatrix freeSpeedTravelTimeSparseMatrix, int zoneIterations) { + this.network = network; + this.timeRadius = timeRadius; + this.freeSpeedTravelTimeSparseMatrix = freeSpeedTravelTimeSparseMatrix; + this.zoneGenerationIterations = zoneIterations; + linksTobeCovered.addAll(network.getLinks().keySet()); + log.info(linksTobeCovered.size() + " links on the network are to be covered"); + } + + public static class Builder { + private final Network network; + + private double timeRadius = 300; + private double sparseMatrixMaxDistance = 10000; + private TravelTime travelTime = new QSimFreeSpeedTravelTime(1); + private TravelDisutility travelDisutility = new TimeAsTravelDisutility(travelTime); + private int zoneIterations = 0; + + public Builder(Network network) { + this.network = network; + } + + public Builder setTimeRadius(double timeRadius) { + this.timeRadius = timeRadius; + return this; + } + + public Builder setSparseMatrixMaxDistance(double sparseMatrixMaxDistance) { + this.sparseMatrixMaxDistance = sparseMatrixMaxDistance; + return this; + } + + public Builder setTravelTime(TravelTime travelTime) { + this.travelTime = travelTime; + return this; + } + + public Builder setTravelDisutility(TravelDisutility travelDisutility) { + this.travelDisutility = travelDisutility; + return this; + } + + public Builder setZoneIterations(int zoneIterations) { + this.zoneIterations = zoneIterations; + return this; + } + + public MaxTravelTimeBasedZoneGenerator build() { + SparseMatrix freeSpeedTravelTimeSparseMatrix = TravelTimeMatrices.calculateTravelTimeSparseMatrix( + new TravelTimeMatrices.RoutingParams(network, travelTime, travelDisutility, Runtime.getRuntime().availableProcessors()), + sparseMatrixMaxDistance, 0, 0).orElseThrow(); + return new MaxTravelTimeBasedZoneGenerator(network, timeRadius, + freeSpeedTravelTimeSparseMatrix, zoneIterations); + } + } + + public Network compute(){ + analyzeNetwork(); + selectInitialCentroids(); + generateZones(); + writeZonesInfoToAttributes(); + return network; + } + + private void analyzeNetwork() { + // Explore reachable links + log.info("Begin analyzing network. This may take some time..."); + int numOfNodesInNetwork = network.getNodes().size(); + ProgressPrinter networkAnalysisCounter = new ProgressPrinter("Network analysis", numOfNodesInNetwork); + + network.getNodes().keySet().forEach(nodeId -> reachableLinksMap.put(nodeId, new HashSet<>())); + for (Node node1 : network.getNodes().values()) { + // All outgoing links from this node are considered reachable + node1.getOutLinks().values().stream() + .filter(link -> linksTobeCovered.contains(link.getId())) + .forEach(link -> reachableLinksMap.get(node1.getId()).add(link.getId())); + for (Node node2 : network.getNodes().values()) { + // if same node, then skip + if (node1.getId().toString().equals(node2.getId().toString())) { + continue; + } + + double node1ToNode2TravelTime = freeSpeedTravelTimeSparseMatrix.get(node1, node2); + double node2ToNode1TravelTime = freeSpeedTravelTimeSparseMatrix.get(node2, node1); + // if the node 2 is too far away from node 1, then skip + if (node1ToNode2TravelTime == -1 || node2ToNode1TravelTime == -1 || + node1ToNode2TravelTime > timeRadius || node2ToNode1TravelTime > timeRadius) { + // note: -1 means not even recorded in the sparse matrix --> too far away + continue; + } + + // if we reach here, node 2 is reachable from node 1. Then, we check each outgoing links from node 2 + for (Link link : node2.getOutLinks().values()) { + if (linksTobeCovered.contains(link.getId())) { + double linkTravelTime = Math.floor(link.getLength() / link.getFreespeed()) + 1; + if (2 + node1ToNode2TravelTime + linkTravelTime <= timeRadius) { + // above is how VRP travel time calculated + reachableLinksMap.get(node1.getId()).add(link.getId()); + } + } + } + } + // node1 is analyzed, move on to next node + networkAnalysisCounter.countUp(); + } + } + + private void selectInitialCentroids() { + log.info("Begin selecting centroids. This may take some time..."); + int totalLinksToCover = linksTobeCovered.size(); + ProgressPrinter centroidSelectionPrinter = new ProgressPrinter("Initial centroid selection", totalLinksToCover); + + // Copy the reachable links map,including copying the sets in the values of the map + Map, Set>> newlyCoveredLinksMap = createReachableLInksMapCopy(); + + // Initialize uncovered links + Set> uncoveredLinkIds = new HashSet<>(linksTobeCovered); + while (!uncoveredLinkIds.isEmpty()) { + // score the links + Map, Double> nodesScoresMap = scoreTheNodes(newlyCoveredLinksMap); + + // choose the centroid based on score map + Id selectedNodeId = selectBasedOnScoreMap(nodesScoresMap); + + // add that node to the zonal system + zonalSystemData.put(selectedNodeId, new ArrayList<>()); + + // remove all the newly covered links from the uncoveredLinkIds + uncoveredLinkIds.removeAll(reachableLinksMap.get(selectedNodeId)); + + // update the newlyCoveredLinksMap by removing links that are already covered + for (Id nodeId : newlyCoveredLinksMap.keySet()) { + newlyCoveredLinksMap.get(nodeId).removeAll(reachableLinksMap.get(selectedNodeId)); + } + + // Print the progress + int numLinksAlreadyCovered = totalLinksToCover - uncoveredLinkIds.size(); + centroidSelectionPrinter.countTo(numLinksAlreadyCovered); + } + + log.info("Potential centroids identified. There are in total " + zonalSystemData.size() + " potential centroid points"); + // remove redundant centroid + removeRedundantCentroid(); + + } + + private void generateZones() { + log.info("Assigning links to the closest centroid"); + assignLinksToNearestZone(); + + // after the zone is generated, update the location of the centroids (move to a better location) + // this will lead to an updated zonal system --> we may need to run multiple iterations + for (int i = 0; i < zoneGenerationIterations; i++) { + int it = i + 1; + log.info("Improving zones now. Iteration #" + it + " out of " + zoneGenerationIterations); + + List> updatedCentroids = new ArrayList<>(); + for (Id originalZoneCentroidNodeId : zonalSystemData.keySet()) { + Node currentBestCentroidNode = network.getNodes().get(originalZoneCentroidNodeId); + List linksInZone = zonalSystemData.get(originalZoneCentroidNodeId); + Set potentialCentroidNodes = new HashSet<>(); + linksInZone.forEach(link -> potentialCentroidNodes.add(link.getToNode())); + + double bestScore = Double.POSITIVE_INFINITY; + for (Node potentialNewCentroidNode : potentialCentroidNodes) { + double cost = 0; + for (Link link : linksInZone) { + if (!linksTobeCovered.contains(link.getId())) { + // if this link is not relevant -> zero cost + continue; + } + if (!reachableLinksMap.get(potentialNewCentroidNode.getId()).contains(link.getId())) { + // if some link in the original zone is not reachable from here, this node cannot be a centroid + cost = Double.POSITIVE_INFINITY; + break; + } + cost += calculateVrpNodeToLinkTravelTime(potentialNewCentroidNode, link); + } + + if (cost < bestScore) { + bestScore = cost; + currentBestCentroidNode = potentialNewCentroidNode; + } + } + updatedCentroids.add(currentBestCentroidNode.getId()); + } + + // re-generate the zone based on updated centroids + zonalSystemData.clear(); + updatedCentroids.forEach(zoneId -> zonalSystemData.put(zoneId, new ArrayList<>())); + removeRedundantCentroid(); + assignLinksToNearestZone(); + } + } + + private void writeZonesInfoToAttributes() { + // Identify the neighbours for each zone, such that we can color the neighboring zones in different colors + Map> zoneNeighborsMap = new HashMap<>(); + zonalSystemData.keySet().forEach(nodeId -> zoneNeighborsMap.put(nodeId.toString(), new HashSet<>())); + List centroids = new ArrayList<>(zoneNeighborsMap.keySet()); + int numZones = centroids.size(); + for (int i = 0; i < numZones; i++) { + String zoneI = centroids.get(i); + for (int j = i + 1; j < numZones; j++) { + String zoneJ = centroids.get(j); + + Set nodesInZoneI = new HashSet<>(); + zonalSystemData.get(Id.createNodeId(zoneI)).forEach(link -> nodesInZoneI.add(link.getFromNode())); + zonalSystemData.get(Id.createNodeId(zoneI)).forEach(link -> nodesInZoneI.add(link.getToNode())); + + Set nodesInZoneJ = new HashSet<>(); + zonalSystemData.get(Id.createNodeId(zoneJ)).forEach(link -> nodesInZoneJ.add(link.getFromNode())); + zonalSystemData.get(Id.createNodeId(zoneJ)).forEach(link -> nodesInZoneJ.add(link.getToNode())); + + if (!Collections.disjoint(nodesInZoneI, nodesInZoneJ)) { + // If two zones shared any node, then we know they are neighbors + zoneNeighborsMap.get(zoneI).add(zoneJ); + zoneNeighborsMap.get(zoneJ).add(zoneI); + } + } + } + + // Add attribute to the link for visualisation + log.info("Marking links in each zone"); + // Determine the color of each zone (for visualisation) + Map coloringMap = new HashMap<>(); + zoneNeighborsMap.keySet().forEach(zoneId -> coloringMap.put(zoneId, 0)); + for (String zoneId : zoneNeighborsMap.keySet()) { + Set usedColor = new HashSet<>(); + for (String neighboringZone : zoneNeighborsMap.get(zoneId)) { + usedColor.add(coloringMap.get(neighboringZone)); + } + boolean colorFound = false; + int i = 1; + while (!colorFound) { + if (usedColor.contains(i)) { + i++; + } else { + colorFound = true; + } + } + coloringMap.put(zoneId, i); + } + + // Marking the color idx of each link + for (Id centroidNodeId : zonalSystemData.keySet()) { + int color = coloringMap.get(centroidNodeId.toString()); + for (Link link : zonalSystemData.get(centroidNodeId)) { + link.getAttributes().putAttribute("zone_color", color); + link.getAttributes().putAttribute("zone_id", centroidNodeId.toString()); + } + } + + // Marking the relevant links (i.e. links to be covered) + for (Id linkId : network.getLinks().keySet()) { + if (linksTobeCovered.contains(linkId)) { + network.getLinks().get(linkId).getAttributes().putAttribute("relevant", "yes"); + } else { + network.getLinks().get(linkId).getAttributes().putAttribute("relevant", "no"); + } + } + + // Marking centroid nodes + for (Node node : network.getNodes().values()) { + if (zonalSystemData.containsKey(node.getId())) { + node.getAttributes().putAttribute("isCentroid", "yes"); + node.getAttributes().putAttribute("zone_color", coloringMap.get(node.getId().toString())); + } else { + node.getAttributes().putAttribute("isCentroid", "no"); + node.getAttributes().putAttribute("zone_color", Double.NaN); + } + } + } + + private Map, Set>> createReachableLInksMapCopy() { + Map, Set>> reachableLinksMapCopy = new HashMap<>(); + for (Id nodeId : network.getNodes().keySet()) { + reachableLinksMapCopy.put(nodeId, new HashSet<>(reachableLinksMap.get(nodeId))); + } + return reachableLinksMapCopy; + } + + private Map, Double> scoreTheNodes(Map, Set>> newlyCoveredLinksMap) { + // Current implementation: simply count the number of newly covered links + Map, Double> nodeScoresMap = new HashMap<>(); + for (Node node : network.getNodes().values()) { + Set> newlyCoveredLinkIds = newlyCoveredLinksMap.get(node.getId()); + double score = newlyCoveredLinkIds.size(); + nodeScoresMap.put(node.getId(), score); + } + return nodeScoresMap; + } + + private Id selectBasedOnScoreMap(Map, Double> nodesScoresMap) { + // Current implementation: Simply choose the link with best score + Id selectedNodeId = null; + double bestScore = 0; + for (Id nodeId : nodesScoresMap.keySet()) { + if (nodesScoresMap.get(nodeId) > bestScore) { + bestScore = nodesScoresMap.get(nodeId); + selectedNodeId = nodeId; + } + } + return selectedNodeId; + } + + private void removeRedundantCentroid() { + // Find all redundant centroids + log.info("Checking for redundant centroids"); + Set> redundantCentroids = identifyRedundantCentroids(); + log.info("Number of redundant centroids identified = " + redundantCentroids.size()); + + // Remove the redundant centroid that covers the minimum number of links + while (!redundantCentroids.isEmpty()) { + int minReachableLinks = Integer.MAX_VALUE; + Id centroidToRemove = null; + for (Id redundantCentroid : redundantCentroids) { + int numReachableLinks = reachableLinksMap.get(redundantCentroid).size(); + if (numReachableLinks < minReachableLinks) { + minReachableLinks = numReachableLinks; + centroidToRemove = redundantCentroid; + } + } + zonalSystemData.remove(centroidToRemove); + + // update redundant centroids set + redundantCentroids = identifyRedundantCentroids(); + log.info("Removing in progress: " + redundantCentroids.size() + " redundant centroids (i.e., zones) left"); + } + log.info("After removal, there are " + zonalSystemData.size() + " centroids (i.e., zones) remaining"); + } + + protected Set> identifyRedundantCentroids() { + Set> redundantCentroids = new HashSet<>(); + for (Id centroidNodeId : zonalSystemData.keySet()) { + Set> uniqueReachableLinkIds = new HashSet<>(reachableLinksMap.get(centroidNodeId)); + for (Id anotherCentriodNodeId : zonalSystemData.keySet()) { + if (centroidNodeId.toString().equals(anotherCentriodNodeId.toString())) { + // skip itself + continue; + } + uniqueReachableLinkIds.removeAll(reachableLinksMap.get(anotherCentriodNodeId)); + } + if (uniqueReachableLinkIds.isEmpty()) { + // There is no unique links covered by this zone, this zone is redundant + redundantCentroids.add(centroidNodeId); + } + } + return redundantCentroids; + } + + private void assignLinksToNearestZone() { + log.info("Assigning links into nearest zones (i.e., nearest centroid)"); + for (Link linkBeingAssigned : network.getLinks().values()) { + // Find the closest centroid and assign the link to that zone + double minDistance = Double.POSITIVE_INFINITY; + Id closestCentralNodeId = zonalSystemData.keySet().iterator().next(); + // Assign to a random centroid as initialization + for (Id centroidNodeId : zonalSystemData.keySet()) { + Node centroidNode = network.getNodes().get(centroidNodeId); + double distance = calculateVrpNodeToLinkTravelTime(centroidNode, linkBeingAssigned); + if (distance < minDistance) { + minDistance = distance; + closestCentralNodeId = centroidNodeId; + } + } + zonalSystemData.get(closestCentralNodeId).add(linkBeingAssigned); + } + } + + private double calculateVrpNodeToLinkTravelTime(Node fromNode, Link toLink) { + if (freeSpeedTravelTimeSparseMatrix.get(fromNode, toLink.getFromNode()) == -1) { + return Double.POSITIVE_INFINITY; + } + return freeSpeedTravelTimeSparseMatrix.get(fromNode, toLink.getFromNode()) + + Math.ceil(toLink.getLength() / toLink.getFreespeed()) + 2; + } +} diff --git a/contribs/application/src/main/java/org/matsim/application/prepare/network/zone_preparation/PrepareMaxTravelTimeBasedZonalSystem.java b/contribs/application/src/main/java/org/matsim/application/prepare/network/zone_preparation/PrepareMaxTravelTimeBasedZonalSystem.java new file mode 100644 index 00000000000..ab3b543190d --- /dev/null +++ b/contribs/application/src/main/java/org/matsim/application/prepare/network/zone_preparation/PrepareMaxTravelTimeBasedZonalSystem.java @@ -0,0 +1,110 @@ +package org.matsim.application.prepare.network.zone_preparation; + +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.geom.Point; +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.NetworkWriter; +import org.matsim.api.core.v01.network.Node; +import org.matsim.application.MATSimAppCommand; +import org.matsim.application.options.ShpOptions; +import org.matsim.core.config.ConfigUtils; +import org.matsim.core.network.NetworkUtils; +import org.matsim.core.network.algorithms.NetworkCleaner; +import org.matsim.core.network.algorithms.TransportModeNetworkFilter; +import org.matsim.core.scenario.ScenarioUtils; +import org.matsim.core.utils.geometry.geotools.MGC; +import picocli.CommandLine; + +import java.util.*; + +public class PrepareMaxTravelTimeBasedZonalSystem implements MATSimAppCommand { + @CommandLine.Option(names = "--input", required = true, description = "input network path") + private String inputNetworkPath; + + @CommandLine.Option(names = "--output", required = true, description = "output network path") + private String outputNetworkPath; + + @CommandLine.Option(names = "--max-travel-time", defaultValue = "300", description = "max time distance away from zone centroid [second]") + private double maxTimeDistance; + + @CommandLine.Option(names = "--iterations", defaultValue = "20", description = "number of iterations reduce number of zones") + private int iterations; + + @CommandLine.Option(names = "--network-modes", description = "filter the network based on the modes we are interested in", split = ",", defaultValue = "car") + private List networkModes; + + // Optional shp input for network filtering + @CommandLine.Mixin + private ShpOptions shp = new ShpOptions(); + + @Override + public Integer call() throws Exception { + Network fullNetwork = NetworkUtils.readNetwork(inputNetworkPath); + + // extract the subnetwork from the full network based on allowed modes + Network subNetwork = ScenarioUtils.loadScenario(ConfigUtils.createConfig()).getNetwork(); + new TransportModeNetworkFilter(fullNetwork).filter(subNetwork, new HashSet<>(networkModes)); + + // filter the subnetwork if shp is provided + if (shp.isDefined()){ + filterNetworkWithShp(subNetwork); + } + + // clean the network after the filter process + new NetworkCleaner().run(subNetwork); + + // perform zone-generation on the subnetwork (zone information will be written directly to the attributes of the links in the subnetwork) + MaxTravelTimeBasedZoneGenerator.Builder builder = new MaxTravelTimeBasedZoneGenerator.Builder(subNetwork); + MaxTravelTimeBasedZoneGenerator generator = builder.setTimeRadius(maxTimeDistance).setZoneIterations(iterations).build(); + generator.compute(); + + // add attribute related to zonal information to the full network + for (Id linkId : subNetwork.getLinks().keySet()) { + Link linkInSubNetwork = subNetwork.getLinks().get(linkId); + Link linkInFullNetwork = fullNetwork.getLinks().get(linkId); + for (Map.Entry attribute : linkInSubNetwork.getAttributes().getAsMap().entrySet()) { + // if the newly written attribute (related to zone) does not exist in full network, then add this attribute to the link in full network + if (linkInFullNetwork.getAttributes().getAttribute(attribute.getKey()) == null) { + linkInFullNetwork.getAttributes().putAttribute(attribute.getKey(), attribute.getValue()); + } + } + } + for (Id nodeId : subNetwork.getNodes().keySet()) { + Node nodeInSubNetwork = subNetwork.getNodes().get(nodeId); + Node nodeInFullNetwork = fullNetwork.getNodes().get(nodeId); + for (Map.Entry attribute : nodeInSubNetwork.getAttributes().getAsMap().entrySet()) { + // if the newly written attribute (related to zone) does not exist in full network, then add this attribute to the node in full network + if (nodeInFullNetwork.getAttributes().getAttribute(attribute.getKey()) == null) { + nodeInFullNetwork.getAttributes().putAttribute(attribute.getKey(), attribute.getValue()); + } + } + } + + + // write down the processed full network to the output path + new NetworkWriter(fullNetwork).write(outputNetworkPath); + + return 0; + } + + public static void main(String[] args) { + new PrepareMaxTravelTimeBasedZonalSystem().execute(args); + } + + private void filterNetworkWithShp(Network network){ + Geometry areaToKeep = shp.getGeometry(); + List linksToRemove = new ArrayList<>(); + for (Link link : network.getLinks().values()) { + Point from = MGC.coord2Point(link.getFromNode().getCoord()); + Point to = MGC.coord2Point(link.getToNode().getCoord()); + if (!from.within(areaToKeep) || !to.within(areaToKeep)) { + linksToRemove.add(link); + } + } + for (Link link : linksToRemove) { + network.removeLink(link.getId()); + } + } +} diff --git a/contribs/application/src/main/java/org/matsim/application/prepare/network/zone_preparation/ProgressPrinter.java b/contribs/application/src/main/java/org/matsim/application/prepare/network/zone_preparation/ProgressPrinter.java new file mode 100644 index 00000000000..275a5a462d2 --- /dev/null +++ b/contribs/application/src/main/java/org/matsim/application/prepare/network/zone_preparation/ProgressPrinter.java @@ -0,0 +1,52 @@ +package org.matsim.application.prepare.network.zone_preparation; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class ProgressPrinter { + private static final Logger log = LogManager.getLogger(ProgressPrinter.class); + private final String processName; + private final int mileStone; + private final int stepSize; + private int counter = 0; + private int pct = 0; + private boolean valid = true; + + /** + * Progress printer with customizable step size + */ + public ProgressPrinter(String processName, int totalNumToProcess, int stepSize) { + this.processName = processName; + this.stepSize = stepSize; + this.mileStone = totalNumToProcess / (100 / stepSize); + if (mileStone <= 0) { + valid = false; + } + } + + /** + * By default, step size is 10 (percent) + */ + public ProgressPrinter(String processName, int totalNumToProcess) { + this.processName = processName; + this.stepSize = 10; + this.mileStone = totalNumToProcess / this.stepSize; + if (mileStone <= 0) { + valid = false; + } + } + + public void countUp() { + counter++; + if (valid && counter % mileStone == 0) { + pct += stepSize; + log.info(processName + " in progress: " + pct + "% completed"); + } + } + + public void countTo(int currentProgress) { + while (counter < currentProgress) { + countUp(); + } + } +} diff --git a/contribs/common/pom.xml b/contribs/common/pom.xml index 210daca7aa9..9d59862c307 100644 --- a/contribs/common/pom.xml +++ b/contribs/common/pom.xml @@ -28,5 +28,5 @@ h3 4.1.1 - + diff --git a/contribs/common/src/main/java/org/matsim/contrib/common/zones/ZoneSystemUtils.java b/contribs/common/src/main/java/org/matsim/contrib/common/zones/ZoneSystemUtils.java index d679bc2c2bb..ef27a3ebc4b 100644 --- a/contribs/common/src/main/java/org/matsim/contrib/common/zones/ZoneSystemUtils.java +++ b/contribs/common/src/main/java/org/matsim/contrib/common/zones/ZoneSystemUtils.java @@ -20,6 +20,8 @@ import org.matsim.contrib.common.util.DistanceUtils; import org.matsim.contrib.common.zones.io.ZoneShpReader; import org.matsim.contrib.common.zones.io.ZoneXmlReader; +import org.matsim.contrib.common.zones.systems.geom_free_zones.GeometryFreeZoneSystem; +import org.matsim.contrib.common.zones.systems.geom_free_zones.GeometryFreeZoneSystemParams; import org.matsim.contrib.common.zones.systems.grid.GISFileZoneSystemParams; import org.matsim.contrib.common.zones.systems.grid.h3.H3GridZoneSystemParams; import org.matsim.contrib.common.zones.systems.grid.h3.H3ZoneSystem; @@ -81,8 +83,9 @@ public static ZoneSystem createZoneSystem(@Nullable URL context, @Nonnull Networ case H3GridZoneSystemParams.SET_NAME -> { Preconditions.checkNotNull(((H3GridZoneSystemParams) zoneSystemParams).h3Resolution); Preconditions.checkNotNull(crs); - yield new H3ZoneSystem(crs, ((H3GridZoneSystemParams) zoneSystemParams).h3Resolution, network, zoneFilter); + yield new H3ZoneSystem(crs, ((H3GridZoneSystemParams) zoneSystemParams).h3Resolution, network, zoneFilter); } + case GeometryFreeZoneSystemParams.SET_NAME -> new GeometryFreeZoneSystem(network); default -> throw new IllegalStateException("Unexpected value: " + zoneSystemParams.getName()); }; return zoneSystem; diff --git a/contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/geom_free_zones/GeometryFreeZoneSystem.java b/contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/geom_free_zones/GeometryFreeZoneSystem.java new file mode 100644 index 00000000000..2a081dc5d05 --- /dev/null +++ b/contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/geom_free_zones/GeometryFreeZoneSystem.java @@ -0,0 +1,61 @@ +package org.matsim.contrib.common.zones.systems.geom_free_zones; + +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.Node; +import org.matsim.contrib.common.zones.Zone; +import org.matsim.contrib.common.zones.ZoneImpl; +import org.matsim.contrib.common.zones.ZoneSystem; + +import java.util.*; + +import static org.matsim.contrib.common.zones.systems.geom_free_zones.GeometryFreeZoneSystemParams.SET_NAME; +import static org.matsim.contrib.common.zones.systems.geom_free_zones.GeometryFreeZoneSystemParams.ZONE_ID; + +public class GeometryFreeZoneSystem implements ZoneSystem { + private final Map, Zone> zones = new HashMap<>(); + private final Map, List> linksForZones = new HashMap<>(); + private final Map, Zone> zoneForLinks = new HashMap<>(); + private final Map, Zone> zoneForNodes = new HashMap<>(); + + public GeometryFreeZoneSystem(Network network) { + for (Link link : network.getLinks().values()) { + String zoneIdString = (String) link.getAttributes().getAttribute(ZONE_ID); + Id zoneId = Id.create(zoneIdString, Zone.class); + Zone zone; + if (!zones.containsKey(zoneId)) { + // zone has not yet been created + zone = new ZoneImpl(zoneId, null, SET_NAME); + zones.put(zoneId, zone); + linksForZones.put(zoneId, List.of(link)); + } else { + // zone already created + zone = zones.get(zoneId); + linksForZones.get(zoneId).add(link); + } + zoneForLinks.put(link.getId(), zone); + zoneForNodes.put(link.getToNode().getId(), zone); + } + } + + @Override + public Optional getZoneForLinkId(Id link) { + return zoneForLinks.containsKey(link) ? Optional.of(zoneForNodes.get(link)) : Optional.empty(); + } + + @Override + public Optional getZoneForNodeId(Id nodeId) { + return zoneForNodes.containsKey(nodeId) ? Optional.of(zoneForNodes.get(nodeId)) : Optional.empty(); + } + + @Override + public List getLinksForZoneId(Id zone) { + return linksForZones.get(zone); + } + + @Override + public Map, Zone> getZones() { + return zones; + } +} diff --git a/contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/geom_free_zones/GeometryFreeZoneSystemParams.java b/contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/geom_free_zones/GeometryFreeZoneSystemParams.java new file mode 100644 index 00000000000..5d17c83e8c1 --- /dev/null +++ b/contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/geom_free_zones/GeometryFreeZoneSystemParams.java @@ -0,0 +1,32 @@ +package org.matsim.contrib.common.zones.systems.geom_free_zones; + +import com.google.common.base.Verify; +import jakarta.validation.constraints.Positive; +import org.matsim.api.core.v01.Scenario; +import org.matsim.api.core.v01.network.Network; +import org.matsim.contrib.common.zones.ZoneSystemParams; +import org.matsim.core.config.Config; +import org.matsim.core.network.NetworkUtils; +import org.matsim.core.scenario.ScenarioUtils; + +/** + * Generate geometry-free zones based on network directly. Additional attribute in link is required: zone_id + */ +public class GeometryFreeZoneSystemParams extends ZoneSystemParams { + + public static final String SET_NAME = "GeometryFreeZoneSystem"; + public static final String ZONE_ID = "zoneId"; + + public GeometryFreeZoneSystemParams() { + super(SET_NAME); + } + + @Override + protected void checkConsistency(Config config) { + super.checkConsistency(config); + Network network = ScenarioUtils.createScenario(config).getNetwork(); + // Here, we check one arbitrary link from the (sub-)network used for DVRP/DRT vehicles and see if there is a zone ID attribute + Verify.verify(network.getLinks().values().iterator().next().getAttributes().getAttribute(ZONE_ID) != null, + "Zone id attribute not set"); + } +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtZoneSystemParams.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtZoneSystemParams.java index 5608a30b944..9e916128860 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtZoneSystemParams.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtZoneSystemParams.java @@ -24,6 +24,7 @@ import org.matsim.contrib.common.util.ReflectiveConfigGroupWithConfigurableParameterSets; import org.matsim.contrib.common.zones.GridZoneSystem; import org.matsim.contrib.common.zones.ZoneSystemParams; +import org.matsim.contrib.common.zones.systems.geom_free_zones.GeometryFreeZoneSystemParams; import org.matsim.contrib.common.zones.systems.grid.GISFileZoneSystemParams; import org.matsim.contrib.common.zones.systems.grid.h3.H3GridZoneSystemParams; import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystemParams; @@ -65,6 +66,10 @@ private void initSingletonParameterSets() { addDefinition(H3GridZoneSystemParams.SET_NAME, H3GridZoneSystemParams::new, () -> zoneSystemParams, params -> zoneSystemParams = (H3GridZoneSystemParams)params); + + addDefinition(GeometryFreeZoneSystemParams.SET_NAME, GeometryFreeZoneSystemParams::new, + () -> zoneSystemParams, + params -> zoneSystemParams = (GeometryFreeZoneSystemParams)params); } @Override @@ -85,6 +90,9 @@ public void handleAddUnknownParam(String paramName, String value) { addParameterSet(createParameterSet(H3GridZoneSystemParams.SET_NAME)); break; } + case "GeometryFree":{ + addParameterSet(createParameterSet(GeometryFreeZoneSystemParams.SET_NAME)); + } default: super.handleAddUnknownParam(paramName, value); } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/DvrpTravelTimeMatrixParams.java b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/DvrpTravelTimeMatrixParams.java index 77e717cfea7..a12930c5d42 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/DvrpTravelTimeMatrixParams.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/DvrpTravelTimeMatrixParams.java @@ -23,6 +23,7 @@ import jakarta.validation.constraints.PositiveOrZero; import org.matsim.contrib.common.util.ReflectiveConfigGroupWithConfigurableParameterSets; import org.matsim.contrib.common.zones.ZoneSystemParams; +import org.matsim.contrib.common.zones.systems.geom_free_zones.GeometryFreeZoneSystemParams; import org.matsim.contrib.common.zones.systems.grid.GISFileZoneSystemParams; import org.matsim.contrib.common.zones.systems.grid.h3.H3GridZoneSystemParams; import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystemParams; @@ -77,6 +78,10 @@ private void initSingletonParameterSets() { addDefinition(H3GridZoneSystemParams.SET_NAME, H3GridZoneSystemParams::new, () -> zoneSystemParams, params -> zoneSystemParams = (H3GridZoneSystemParams)params); + + addDefinition(GeometryFreeZoneSystemParams.SET_NAME, GeometryFreeZoneSystemParams::new, + () -> zoneSystemParams, + params -> zoneSystemParams = (GeometryFreeZoneSystemParams)params); } @Override From c941086de8423f9f8ee85ae6bcea810f47127b78 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Sep 2024 18:36:11 +0000 Subject: [PATCH 13/27] Bump org.apache.commons:commons-compress from 1.26.2 to 1.27.1 Bumps org.apache.commons:commons-compress from 1.26.2 to 1.27.1. --- updated-dependencies: - dependency-name: org.apache.commons:commons-compress dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 58c7d09aaf5..487fb935643 100644 --- a/pom.xml +++ b/pom.xml @@ -118,7 +118,7 @@ org.apache.commons commons-compress - 1.26.2 + 1.27.1 commons-logging From 4cffcecdc5c58255430d850beb49e6a2cae585e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Sep 2024 18:37:07 +0000 Subject: [PATCH 14/27] Bump org.apache.maven.plugins:maven-failsafe-plugin from 3.3.1 to 3.5.0 Bumps [org.apache.maven.plugins:maven-failsafe-plugin](https://github.com/apache/maven-surefire) from 3.3.1 to 3.5.0. - [Release notes](https://github.com/apache/maven-surefire/releases) - [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.3.1...surefire-3.5.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-failsafe-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 487fb935643..db7baf6473b 100644 --- a/pom.xml +++ b/pom.xml @@ -425,7 +425,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 3.3.1 + 3.5.0 org.apache.maven.plugins From 9f77ca444a585afa8992a37e47ee6a0b02c760fe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Sep 2024 18:37:08 +0000 Subject: [PATCH 15/27] Bump org.apache.maven.plugins:maven-install-plugin from 3.1.2 to 3.1.3 Bumps [org.apache.maven.plugins:maven-install-plugin](https://github.com/apache/maven-install-plugin) from 3.1.2 to 3.1.3. - [Release notes](https://github.com/apache/maven-install-plugin/releases) - [Commits](https://github.com/apache/maven-install-plugin/compare/maven-install-plugin-3.1.2...maven-install-plugin-3.1.3) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-install-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 487fb935643..cffe1634a50 100644 --- a/pom.xml +++ b/pom.xml @@ -445,7 +445,7 @@ org.apache.maven.plugins maven-install-plugin - 3.1.2 + 3.1.3 org.apache.maven.plugins From b68aefc059f5d00d2ef0f1d1371703ab1a35f315 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Sep 2024 20:21:26 +0000 Subject: [PATCH 16/27] Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.7.0 to 3.10.0 Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.7.0 to 3.10.0. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.7.0...maven-javadoc-plugin-3.10.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 61d1e67d8e0..917b4b79377 100644 --- a/pom.xml +++ b/pom.xml @@ -450,7 +450,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.7.0 + 3.10.0 org.codehaus.mojo From 25dd4d3498bebc886f50f46536dc2fb25d8063bb Mon Sep 17 00:00:00 2001 From: rakow Date: Mon, 9 Sep 2024 09:40:43 +0200 Subject: [PATCH 17/27] revert to old pseudo network creator --- .../matsim/pt/utils/CreatePseudoNetwork.java | 117 +++++++++----- .../CreatePseudoNetworkWithLoopLinks.java | 153 ++++++++++++++++++ 2 files changed, 229 insertions(+), 41 deletions(-) create mode 100644 matsim/src/main/java/org/matsim/pt/utils/CreatePseudoNetworkWithLoopLinks.java diff --git a/matsim/src/main/java/org/matsim/pt/utils/CreatePseudoNetwork.java b/matsim/src/main/java/org/matsim/pt/utils/CreatePseudoNetwork.java index 30ab02ad413..906c97396ee 100644 --- a/matsim/src/main/java/org/matsim/pt/utils/CreatePseudoNetwork.java +++ b/matsim/src/main/java/org/matsim/pt/utils/CreatePseudoNetwork.java @@ -41,15 +41,18 @@ import org.matsim.pt.transitSchedule.api.TransitRoute; import org.matsim.pt.transitSchedule.api.TransitRouteStop; import org.matsim.pt.transitSchedule.api.TransitSchedule; +import org.matsim.pt.transitSchedule.api.TransitStopArea; import org.matsim.pt.transitSchedule.api.TransitStopFacility; /** * Builds a network where transit vehicles can drive along and assigns the correct - * links to the transit stop facilities and routes of transit lines. Each stop facility - * is assigned to a loop link, located in a node with the same coordinates as the stop. - * The stop facility ID is used for node and link IDs. + * links to the transit stop facilities and routes of transit lines. As each transit + * stop facility can only be connected to at most one link, the algorithm is forced + * to duplicated transit stop facilities in certain cases to build the network. * - * @author mrieser, davibicudo + * See {@link CreatePseudoNetworkWithLoopLinks} for a version that uses loop links instead of duplicating stop facilities. + * + * @author mrieser */ public class CreatePseudoNetwork { @@ -59,8 +62,13 @@ public class CreatePseudoNetwork { private final double linkFreeSpeed; private final double linkCapacity; - private final Map, Link> links = new HashMap<>(); - private final Map nodes = new HashMap<>(); + + private final Map, Link> links = new HashMap, Link>(); + private final Map, TransitStopFacility> stopFacilities = new HashMap, TransitStopFacility>(); + private final Map nodes = new HashMap(); + private final Map> facilityCopies = new HashMap>(); + + private long linkIdCounter = 0; private final Set transitModes = Collections.singleton(TransportMode.pt); @@ -83,27 +91,24 @@ public CreatePseudoNetwork(final TransitSchedule schedule, final Network network public void createNetwork() { - createStopNodesAndLoopLinks(); + List> toBeRemoved = new LinkedList>(); - List> toBeRemoved = new LinkedList<>(); for (TransitLine tLine : this.schedule.getTransitLines().values()) { for (TransitRoute tRoute : tLine.getRoutes().values()) { - ArrayList> routeLinks = new ArrayList<>(); + ArrayList> routeLinks = new ArrayList>(); TransitRouteStop prevStop = null; for (TransitRouteStop stop : tRoute.getStops()) { - if (prevStop != null) { - Link link = getNetworkLink(prevStop, stop); - routeLinks.add(link.getId()); - } + Link link = getNetworkLink(prevStop, stop); + routeLinks.add(link.getId()); prevStop = stop; } - if (!routeLinks.isEmpty()) { - NetworkRoute route = RouteUtils.createNetworkRoute(routeLinks); + if (routeLinks.size() > 0) { + NetworkRoute route = RouteUtils.createNetworkRoute(routeLinks ); tRoute.setRoute(route); } else { System.err.println("Line " + tLine.getId() + " route " + tRoute.getId() + " has less than two stops. Removing this route from schedule."); - toBeRemoved.add(new Tuple<>(tLine, tRoute)); + toBeRemoved.add(new Tuple(tLine, tRoute)); } } } @@ -113,41 +118,64 @@ public void createNetwork() { } } - private void createStopNodesAndLoopLinks() { - for (TransitStopFacility stop : this.schedule.getFacilities().values()) { - Node node = this.network.getFactory().createNode(Id.createNodeId(this.prefix + stop.getId()), stop.getCoord()); - this.network.addNode(node); - this.nodes.put(stop, node); - - Link loopLink = this.network.getFactory().createLink(Id.createLinkId (this.prefix + stop.getId()), node, node); - loopLink.setAllowedModes(this.transitModes); - stop.setLinkId(loopLink.getId()); - this.network.addLink(loopLink); - Tuple connection = new Tuple<>(node, node); - this.links.put(connection, loopLink); - } - } - private Link getNetworkLink(final TransitRouteStop fromStop, final TransitRouteStop toStop) { - TransitStopFacility fromFacility = fromStop.getStopFacility(); + TransitStopFacility fromFacility = (fromStop == null) ? toStop.getStopFacility() : fromStop.getStopFacility(); TransitStopFacility toFacility = toStop.getStopFacility(); Node fromNode = this.nodes.get(fromFacility); + if (fromNode == null) { + fromNode = this.network.getFactory().createNode(Id.create(this.prefix + toFacility.getId(), Node.class), fromFacility.getCoord()); + this.network.addNode(fromNode); + this.nodes.put(toFacility, fromNode); + } + Node toNode = this.nodes.get(toFacility); + if (toNode == null) { + toNode = this.network.getFactory().createNode(Id.create(this.prefix + toFacility.getId(), Node.class), toFacility.getCoord()); + this.network.addNode(toNode); + this.nodes.put(toFacility, toNode); + } - Tuple connection = new Tuple<>(fromNode, toNode); + Tuple connection = new Tuple(fromNode, toNode); Link link = this.links.get(connection); - return link == null ? createAndAddLink(connection) : link; + if (link == null) { + link = createAndAddLink(fromNode, toNode, connection); + + if (toFacility.getLinkId() == null) { + toFacility.setLinkId(link.getId()); + this.stopFacilities.put(connection, toFacility); + } else { + List copies = this.facilityCopies.get(toFacility); + if (copies == null) { + copies = new ArrayList(); + this.facilityCopies.put(toFacility, copies); + } + Id newId = Id.create(toFacility.getId().toString() + "." + Integer.toString(copies.size() + 1), TransitStopFacility.class); + TransitStopFacility newFacility = this.schedule.getFactory().createTransitStopFacility(newId, toFacility.getCoord(), toFacility.getIsBlockingLane()); + newFacility.setStopAreaId(Id.create(toFacility.getId(), TransitStopArea.class)); + newFacility.setLinkId(link.getId()); + newFacility.setName(toFacility.getName()); + copies.add(newFacility); + this.nodes.put(newFacility, toNode); + this.schedule.addStopFacility(newFacility); + toStop.setStopFacility(newFacility); + this.stopFacilities.put(connection, newFacility); + } + } else { + toStop.setStopFacility(this.stopFacilities.get(connection)); + } + return link; } - private Link createAndAddLink(Tuple connection) { - Node fromNode = connection.getFirst(); - Node toNode = connection.getSecond(); + private Link createAndAddLink(Node fromNode, Node toNode, + Tuple connection) { Link link; - link = this.network.getFactory().createLink(Id.createLinkId(this.prefix + fromNode.getId() + "-" + toNode.getId()), fromNode, - toNode); - link.setLength(CoordUtils.calcEuclideanDistance(fromNode.getCoord(), toNode.getCoord())); - + link = this.network.getFactory().createLink(Id.create(this.prefix + this.linkIdCounter++, Link.class), fromNode, toNode); + if (fromNode == toNode) { + link.setLength(50); + } else { + link.setLength(CoordUtils.calcEuclideanDistance(fromNode.getCoord(), toNode.getCoord())); + } link.setFreespeed(linkFreeSpeed); link.setCapacity(linkCapacity); link.setNumberOfLanes(1); @@ -157,4 +185,11 @@ private Link createAndAddLink(Tuple connection) { return link; } + public Link getLinkBetweenStops(final TransitStopFacility fromStop, final TransitStopFacility toStop) { + Node fromNode = this.nodes.get(fromStop); + Node toNode = this.nodes.get(toStop); + Tuple connection = new Tuple(fromNode, toNode); + return this.links.get(connection); + } + } diff --git a/matsim/src/main/java/org/matsim/pt/utils/CreatePseudoNetworkWithLoopLinks.java b/matsim/src/main/java/org/matsim/pt/utils/CreatePseudoNetworkWithLoopLinks.java new file mode 100644 index 00000000000..d0532315137 --- /dev/null +++ b/matsim/src/main/java/org/matsim/pt/utils/CreatePseudoNetworkWithLoopLinks.java @@ -0,0 +1,153 @@ +/* *********************************************************************** * + * project: org.matsim.* + * CreatePseudoNetwork + * * + * *********************************************************************** * + * * + * copyright : (C) 2009 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.pt.utils; + +import com.google.common.annotations.Beta; +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.api.core.v01.network.Network; +import org.matsim.api.core.v01.network.Node; +import org.matsim.core.population.routes.NetworkRoute; +import org.matsim.core.population.routes.RouteUtils; +import org.matsim.core.utils.collections.Tuple; +import org.matsim.core.utils.geometry.CoordUtils; +import org.matsim.pt.transitSchedule.api.*; + +import java.util.*; + +/** + * Builds a network where transit vehicles can drive along and assigns the correct + * links to the transit stop facilities and routes of transit lines. Each stop facility + * is assigned to a loop link, located in a node with the same coordinates as the stop. + * The stop facility ID is used for node and link IDs. + * + * @author mrieser, davibicudo + * + * @implNote THis functionality might be merged with {@link CreatePseudoNetwork}. + */ +@Beta +public class CreatePseudoNetworkWithLoopLinks { + + private final TransitSchedule schedule; + private final Network network; + private final String prefix; + private final double linkFreeSpeed; + private final double linkCapacity; + + private final Map, Link> links = new HashMap<>(); + private final Map nodes = new HashMap<>(); + + private final Set transitModes = Collections.singleton(TransportMode.pt); + + public CreatePseudoNetworkWithLoopLinks(final TransitSchedule schedule, final Network network, final String networkIdPrefix) { + this.schedule = schedule; + this.network = network; + this.prefix = networkIdPrefix; + this.linkFreeSpeed = 100.0 / 3.6; + this.linkCapacity = 100000.0; + } + + public CreatePseudoNetworkWithLoopLinks(final TransitSchedule schedule, final Network network, final String networkIdPrefix, + final double linkFreeSpeed, final double linkCapacity) { + this.schedule = schedule; + this.network = network; + this.prefix = networkIdPrefix; + this.linkFreeSpeed = linkFreeSpeed; + this.linkCapacity = linkCapacity; + } + + public void createNetwork() { + + createStopNodesAndLoopLinks(); + + List> toBeRemoved = new LinkedList<>(); + for (TransitLine tLine : this.schedule.getTransitLines().values()) { + for (TransitRoute tRoute : tLine.getRoutes().values()) { + ArrayList> routeLinks = new ArrayList<>(); + TransitRouteStop prevStop = null; + for (TransitRouteStop stop : tRoute.getStops()) { + if (prevStop != null) { + Link link = getNetworkLink(prevStop, stop); + routeLinks.add(link.getId()); + } + prevStop = stop; + } + + if (!routeLinks.isEmpty()) { + NetworkRoute route = RouteUtils.createNetworkRoute(routeLinks); + tRoute.setRoute(route); + } else { + System.err.println("Line " + tLine.getId() + " route " + tRoute.getId() + " has less than two stops. Removing this route from schedule."); + toBeRemoved.add(new Tuple<>(tLine, tRoute)); + } + } + } + + for (Tuple remove : toBeRemoved) { + remove.getFirst().removeRoute(remove.getSecond()); + } + } + + private void createStopNodesAndLoopLinks() { + for (TransitStopFacility stop : this.schedule.getFacilities().values()) { + Node node = this.network.getFactory().createNode(Id.createNodeId(this.prefix + stop.getId()), stop.getCoord()); + this.network.addNode(node); + this.nodes.put(stop, node); + + Link loopLink = this.network.getFactory().createLink(Id.createLinkId (this.prefix + stop.getId()), node, node); + stop.setLinkId(loopLink.getId()); + this.network.addLink(loopLink); + Tuple connection = new Tuple<>(node, node); + this.links.put(connection, loopLink); + } + } + + private Link getNetworkLink(final TransitRouteStop fromStop, final TransitRouteStop toStop) { + TransitStopFacility fromFacility = fromStop.getStopFacility(); + TransitStopFacility toFacility = toStop.getStopFacility(); + + Node fromNode = this.nodes.get(fromFacility); + Node toNode = this.nodes.get(toFacility); + + Tuple connection = new Tuple<>(fromNode, toNode); + Link link = this.links.get(connection); + return link == null ? createAndAddLink(connection) : link; + } + + private Link createAndAddLink(Tuple connection) { + Node fromNode = connection.getFirst(); + Node toNode = connection.getSecond(); + Link link; + link = this.network.getFactory().createLink(Id.createLinkId(this.prefix + fromNode.getId() + "-" + toNode.getId()), fromNode, + toNode); + link.setLength(CoordUtils.calcEuclideanDistance(fromNode.getCoord(), toNode.getCoord())); + + link.setFreespeed(linkFreeSpeed); + link.setCapacity(linkCapacity); + link.setNumberOfLanes(1); + this.network.addLink(link); + link.setAllowedModes(this.transitModes); + this.links.put(connection, link); + return link; + } + +} From baafbd7cb4fc2ab4188b96369d3e591cb2228404 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 14:17:48 +0000 Subject: [PATCH 18/27] Bump com.google.guava:guava from 33.2.1-jre to 33.3.0-jre Bumps [com.google.guava:guava](https://github.com/google/guava) from 33.2.1-jre to 33.3.0-jre. - [Release notes](https://github.com/google/guava/releases) - [Commits](https://github.com/google/guava/commits) --- updated-dependencies: - dependency-name: com.google.guava:guava dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 917b4b79377..cdecc6341d7 100644 --- a/pom.xml +++ b/pom.xml @@ -103,7 +103,7 @@ com.google.guava guava - 33.2.1-jre + 33.3.0-jre org.apache.commons From 575e346c93939c340aef585f6d1d4a3d9521b911 Mon Sep 17 00:00:00 2001 From: simei94 <67737999+simei94@users.noreply.github.com> Date: Mon, 9 Sep 2024 19:35:08 +0200 Subject: [PATCH 19/27] use CsvOptions.detectDelimiter instead of hard coded ';' (#3466) --- .../analysis/noise/MergeNoiseOutput.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/contribs/application/src/main/java/org/matsim/application/analysis/noise/MergeNoiseOutput.java b/contribs/application/src/main/java/org/matsim/application/analysis/noise/MergeNoiseOutput.java index b5b85336c1c..f273ed2b761 100644 --- a/contribs/application/src/main/java/org/matsim/application/analysis/noise/MergeNoiseOutput.java +++ b/contribs/application/src/main/java/org/matsim/application/analysis/noise/MergeNoiseOutput.java @@ -18,6 +18,7 @@ import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.Coord; import org.matsim.application.avro.XYTData; +import org.matsim.application.options.CsvOptions; import org.matsim.core.config.Config; import org.matsim.core.utils.io.IOUtils; import org.matsim.core.utils.misc.Time; @@ -92,7 +93,7 @@ public void setMaxTime(int maxTime) { /** * Merges noise data from multiple files into one file. */ - public void run() { + public void run() throws IOException { mergeReceiverPointData(outputDirectory + "/immissions/", "immission"); mergeReceiverPointData(outputDirectory + "/damages_receiverPoint/", "damages_receiverPoint"); mergeLinkData(outputDirectory.toString() + "/emissions/", "emission"); @@ -116,7 +117,7 @@ private void writeAvro(XYTData xytData, File output) { } } - private void mergeLinkData(String pathParameter, String label) { + private void mergeLinkData(String pathParameter, String label) throws IOException { log.info("Merging emissions data for label {}", label); Object2DoubleMap mergedData = new Object2DoubleOpenHashMap<>(); Table csvOutputMerged = Table.create(TextColumn.create("Link Id"), DoubleColumn.create("value")); @@ -126,9 +127,10 @@ private void mergeLinkData(String pathParameter, String label) { // Read the file Table table = Table.read().csv(CsvReadOptions.builder(IOUtils.getBufferedReader(path)) - .columnTypesPartial(Map.of("Link Id", ColumnType.TEXT)) + .columnTypesPartial(Map.of("Link Id", ColumnType.TEXT, + "Noise Emission " + Time.writeTime(time, Time.TIMEFORMAT_HHMMSS), ColumnType.DOUBLE)) .sample(false) - .separator(';').build()); + .separator(CsvOptions.detectDelimiter(path)).build()); for (Row row : table) { String linkId = row.getString("Link Id"); @@ -157,7 +159,7 @@ private void mergeLinkData(String pathParameter, String label) { * @param outputDir path to the receiverPoint data * @param label label for the receiverPoint data (which kind of data) */ - private void mergeReceiverPointData(String outputDir, String label) { + private void mergeReceiverPointData(String outputDir, String label) throws IOException { // data per time step, maps coord to value Int2ObjectMap> data = new Int2ObjectOpenHashMap<>(); @@ -188,7 +190,7 @@ private void mergeReceiverPointData(String outputDir, String label) { "t", ColumnType.DOUBLE, valueHeader, ColumnType.DOUBLE)) .sample(false) - .separator(';').build()); + .separator(CsvOptions.detectDelimiter(timeDataFile)).build()); // Loop over all rows in the data file for (Row row : dataTable) { @@ -265,7 +267,7 @@ private void mergeReceiverPointData(String outputDir, String label) { // Merges the immissions data @Deprecated - private void mergeImmissionsCSV(String pathParameter, String label) { + private void mergeImmissionsCSV(String pathParameter, String label) throws IOException { log.info("Merging immissions data for label {}", label); Object2DoubleMap mergedData = new Object2DoubleOpenHashMap<>(); @@ -284,7 +286,7 @@ private void mergeImmissionsCSV(String pathParameter, String label) { "Receiver Point Id", ColumnType.INTEGER, "t", ColumnType.DOUBLE)) .sample(false) - .separator(';').build()); + .separator(CsvOptions.detectDelimiter(path)).build()); // Loop over all rows in the file for (Row row : table) { From 7d206a7b3ea1edbbabccdf531ed41e1f8d944534 Mon Sep 17 00:00:00 2001 From: rakow Date: Mon, 9 Sep 2024 20:19:59 +0200 Subject: [PATCH 20/27] Add individual params model for network freespeed (#3467) --- .../network/params/NetworkParamsOpt.java | 1 + .../network/params/ref/IndividualParams.java | 43 +++++++++++++++++++ .../pt/CreateTransitScheduleFromGtfs.java | 18 ++++++-- .../pt/CreateTransitScheduleFromGtfsTest.java | 1 + 4 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 contribs/application/src/main/java/org/matsim/application/prepare/network/params/ref/IndividualParams.java diff --git a/contribs/application/src/main/java/org/matsim/application/prepare/network/params/NetworkParamsOpt.java b/contribs/application/src/main/java/org/matsim/application/prepare/network/params/NetworkParamsOpt.java index e9185fc7a0f..364ad15f036 100644 --- a/contribs/application/src/main/java/org/matsim/application/prepare/network/params/NetworkParamsOpt.java +++ b/contribs/application/src/main/java/org/matsim/application/prepare/network/params/NetworkParamsOpt.java @@ -113,6 +113,7 @@ private static Feature createDefaultFeature(Link link) { String highwayType = NetworkUtils.getHighwayType(link); categories.put("highway_type", highwayType); + ft.put("idx", link.getId().index()); ft.put("speed", NetworkUtils.getAllowedSpeed(link)); ft.put("num_lanes", link.getNumberOfLanes()); ft.put("length", link.getLength()); diff --git a/contribs/application/src/main/java/org/matsim/application/prepare/network/params/ref/IndividualParams.java b/contribs/application/src/main/java/org/matsim/application/prepare/network/params/ref/IndividualParams.java new file mode 100644 index 00000000000..68ab8207611 --- /dev/null +++ b/contribs/application/src/main/java/org/matsim/application/prepare/network/params/ref/IndividualParams.java @@ -0,0 +1,43 @@ +package org.matsim.application.prepare.network.params.ref; + +import it.unimi.dsi.fastutil.objects.Object2DoubleMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectMap; +import org.matsim.application.prepare.Predictor; +import org.matsim.application.prepare.network.params.NetworkModel; + +/** + * Reference model that uses one specific speed factor for each link. + */ +public final class IndividualParams implements NetworkModel { + + private static final Predictor INSTANCE = new Model(); + + @Override + public Predictor speedFactor(String junctionType, String highwayType) { + return INSTANCE; + } + + private static final class Model implements Predictor { + + @Override + public double predict(Object2DoubleMap features, Object2ObjectMap categories) { + return predict(features, categories, new double[0]); + } + + @Override + public double predict(Object2DoubleMap features, Object2ObjectMap categories, double[] params) { + if (params.length == 0) + return 1; + + return params[(int) features.getDouble("idx")]; + } + + @Override + public double[] getData(Object2DoubleMap features, Object2ObjectMap categories) { + return new double[]{ + features.getDouble("idx") + }; + } + } + +} diff --git a/contribs/application/src/main/java/org/matsim/application/prepare/pt/CreateTransitScheduleFromGtfs.java b/contribs/application/src/main/java/org/matsim/application/prepare/pt/CreateTransitScheduleFromGtfs.java index f65bffae57a..5038d1f046c 100644 --- a/contribs/application/src/main/java/org/matsim/application/prepare/pt/CreateTransitScheduleFromGtfs.java +++ b/contribs/application/src/main/java/org/matsim/application/prepare/pt/CreateTransitScheduleFromGtfs.java @@ -7,6 +7,7 @@ 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.TransportMode; import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.network.Network; import org.matsim.api.core.v01.network.NetworkWriter; @@ -199,7 +200,7 @@ private static Scenario getScenarioWithPseudoPtNetworkAndTransitVehicles(Network Scenario scenario = builder.build(); // add pseudo network for pt - new CreatePseudoNetwork(scenario.getTransitSchedule(), scenario.getNetwork(), "pt_", 0.1, 100000.0).createNetwork(); + new CreatePseudoNetwork(scenario.getTransitSchedule(), scenario.getNetwork(), ptNetworkIdentifier, 0.1, 100000.0).createNetwork(); // create TransitVehicle types // see https://svn.vsp.tu-berlin.de/repos/public-svn/publications/vspwp/2014/14-24/ for veh capacities @@ -219,7 +220,6 @@ private static Scenario getScenarioWithPseudoPtNetworkAndTransitVehicles(Network VehicleUtils.setEgressTime(reRbVehicleType, 1.0 / 10.0); // 1s per alighting agent, distributed on 10 doors addHbefaMapping(reRbVehicleType, HbefaVehicleCategory.NON_HBEFA_VEHICLE); - scenario.getTransitVehicles().addVehicleType(reRbVehicleType); } VehicleType sBahnVehicleType = vehicleFactory.createVehicleType(Id.create("S-Bahn_veh_type", VehicleType.class)); @@ -230,6 +230,8 @@ private static Scenario getScenarioWithPseudoPtNetworkAndTransitVehicles(Network VehicleUtils.setDoorOperationMode(sBahnVehicleType, VehicleType.DoorOperationMode.serial); // first finish boarding, then start alighting VehicleUtils.setAccessTime(sBahnVehicleType, 1.0 / 24.0); // 1s per boarding agent, distributed on 8*3 doors VehicleUtils.setEgressTime(sBahnVehicleType, 1.0 / 24.0); // 1s per alighting agent, distributed on 8*3 doors + + addHbefaMapping(sBahnVehicleType, HbefaVehicleCategory.NON_HBEFA_VEHICLE); scenario.getTransitVehicles().addVehicleType(sBahnVehicleType); } VehicleType uBahnVehicleType = vehicleFactory.createVehicleType(Id.create("U-Bahn_veh_type", VehicleType.class)); @@ -240,9 +242,9 @@ private static Scenario getScenarioWithPseudoPtNetworkAndTransitVehicles(Network VehicleUtils.setDoorOperationMode(uBahnVehicleType, VehicleType.DoorOperationMode.serial); // first finish boarding, then start alighting VehicleUtils.setAccessTime(uBahnVehicleType, 1.0 / 18.0); // 1s per boarding agent, distributed on 6*3 doors VehicleUtils.setEgressTime(uBahnVehicleType, 1.0 / 18.0); // 1s per alighting agent, distributed on 6*3 doors - scenario.getTransitVehicles().addVehicleType(uBahnVehicleType); addHbefaMapping(uBahnVehicleType, HbefaVehicleCategory.NON_HBEFA_VEHICLE); + scenario.getTransitVehicles().addVehicleType(uBahnVehicleType); } VehicleType tramVehicleType = vehicleFactory.createVehicleType(Id.create("Tram_veh_type", VehicleType.class)); @@ -253,6 +255,8 @@ private static Scenario getScenarioWithPseudoPtNetworkAndTransitVehicles(Network VehicleUtils.setDoorOperationMode(tramVehicleType, VehicleType.DoorOperationMode.serial); // first finish boarding, then start alighting VehicleUtils.setAccessTime(tramVehicleType, 1.0 / 5.0); // 1s per boarding agent, distributed on 5 doors VehicleUtils.setEgressTime(tramVehicleType, 1.0 / 5.0); // 1s per alighting agent, distributed on 5 doors + + addHbefaMapping(tramVehicleType, HbefaVehicleCategory.NON_HBEFA_VEHICLE); scenario.getTransitVehicles().addVehicleType(tramVehicleType); } VehicleType busVehicleType = vehicleFactory.createVehicleType(Id.create("Bus_veh_type", VehicleType.class)); @@ -263,7 +267,10 @@ private static Scenario getScenarioWithPseudoPtNetworkAndTransitVehicles(Network VehicleUtils.setDoorOperationMode(busVehicleType, VehicleType.DoorOperationMode.serial); // first finish boarding, then start alighting VehicleUtils.setAccessTime(busVehicleType, 1.0 / 3.0); // 1s per boarding agent, distributed on 3 doors VehicleUtils.setEgressTime(busVehicleType, 1.0 / 3.0); // 1s per alighting agent, distributed on 3 doors + + addHbefaMapping(busVehicleType, HbefaVehicleCategory.URBAN_BUS); scenario.getTransitVehicles().addVehicleType(busVehicleType); + } VehicleType ferryVehicleType = vehicleFactory.createVehicleType(Id.create("Ferry_veh_type", VehicleType.class)); { @@ -273,6 +280,8 @@ private static Scenario getScenarioWithPseudoPtNetworkAndTransitVehicles(Network VehicleUtils.setDoorOperationMode(ferryVehicleType, VehicleType.DoorOperationMode.serial); // first finish boarding, then start alighting VehicleUtils.setAccessTime(ferryVehicleType, 1.0 / 1.0); // 1s per boarding agent, distributed on 1 door VehicleUtils.setEgressTime(ferryVehicleType, 1.0 / 1.0); // 1s per alighting agent, distributed on 1 door + + addHbefaMapping(ferryVehicleType, HbefaVehicleCategory.NON_HBEFA_VEHICLE); scenario.getTransitVehicles().addVehicleType(ferryVehicleType); } @@ -284,6 +293,8 @@ private static Scenario getScenarioWithPseudoPtNetworkAndTransitVehicles(Network VehicleUtils.setDoorOperationMode(ptVehicleType, VehicleType.DoorOperationMode.serial); // first finish boarding, then start alighting VehicleUtils.setAccessTime(ptVehicleType, 1.0 / 1.0); // 1s per boarding agent, distributed on 1 door VehicleUtils.setEgressTime(ptVehicleType, 1.0 / 1.0); // 1s per alighting agent, distributed on 1 door + + addHbefaMapping(ptVehicleType, HbefaVehicleCategory.NON_HBEFA_VEHICLE); scenario.getTransitVehicles().addVehicleType(ptVehicleType); } @@ -432,6 +443,7 @@ private static void addHbefaMapping(VehicleType vehicleType, HbefaVehicleCategor VehicleUtils.setHbefaTechnology(carEngineInformation, "average"); VehicleUtils.setHbefaSizeClass(carEngineInformation, "average"); VehicleUtils.setHbefaEmissionsConcept(carEngineInformation, "average"); + vehicleType.setNetworkMode(TransportMode.pt); } private static void increaseLinkFreespeedIfLower(Link link, double newFreespeed) { 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 5b3732f6347..579f2381f4f 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 @@ -30,6 +30,7 @@ void run() { "--network", network.toString(), "--target-crs", "EPSG:4326", "--date", "2019-01-01", + "--validate=true", "--output", output ); From ab554dad76f562cae7cc62f76384d78902faea8e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 20:05:36 +0000 Subject: [PATCH 21/27] Bump org.codehaus.mojo:buildnumber-maven-plugin from 3.2.0 to 3.2.1 Bumps [org.codehaus.mojo:buildnumber-maven-plugin](https://github.com/mojohaus/buildnumber-maven-plugin) from 3.2.0 to 3.2.1. - [Release notes](https://github.com/mojohaus/buildnumber-maven-plugin/releases) - [Commits](https://github.com/mojohaus/buildnumber-maven-plugin/compare/3.2.0...3.2.1) --- updated-dependencies: - dependency-name: org.codehaus.mojo:buildnumber-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cdecc6341d7..c0f2d866e2d 100644 --- a/pom.xml +++ b/pom.xml @@ -455,7 +455,7 @@ org.codehaus.mojo buildnumber-maven-plugin - 3.2.0 + 3.2.1 validate From 692231f2793ec77f023e414907b1f963a56b6ca9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 20:05:37 +0000 Subject: [PATCH 22/27] Bump log4j.version from 2.23.1 to 2.24.0 Bumps `log4j.version` from 2.23.1 to 2.24.0. Updates `org.apache.logging.log4j:log4j-api` from 2.23.1 to 2.24.0 Updates `org.apache.logging.log4j:log4j-core` from 2.23.1 to 2.24.0 Updates `org.apache.logging.log4j:log4j-slf4j2-impl` from 2.23.1 to 2.24.0 --- updated-dependencies: - dependency-name: org.apache.logging.log4j:log4j-api dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.apache.logging.log4j:log4j-core dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.apache.logging.log4j:log4j-slf4j2-impl dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cdecc6341d7..323157754c1 100644 --- a/pom.xml +++ b/pom.xml @@ -30,7 +30,7 @@ 21 - 2.23.1 + 2.24.0 31.3 0.49.2 1.20.0 From f3695136e608f66d3e1c5dfe7449759f612eea1c Mon Sep 17 00:00:00 2001 From: nkuehnel Date: Tue, 10 Sep 2024 22:45:19 +0200 Subject: [PATCH 23/27] drt: add back in max ride time to offer acceptor --- .../matsim/contrib/drt/passenger/DefaultOfferAcceptor.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/passenger/DefaultOfferAcceptor.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/passenger/DefaultOfferAcceptor.java index 9eeed624139..c45e04db6ca 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/passenger/DefaultOfferAcceptor.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/passenger/DefaultOfferAcceptor.java @@ -28,7 +28,9 @@ public Optional acceptDrtOffer(DrtRequest request, double de .newBuilder() .request(request) .earliestStartTime(request.getEarliestStartTime()) + .maxRideDuration(request.getMaxRideDuration()) .latestArrivalTime(Math.min(updatedLatestStartTime + request.getMaxRideDuration(), request.getLatestArrivalTime())) - .latestStartTime(updatedLatestStartTime).build()); + .latestStartTime(updatedLatestStartTime) + .build()); } } From 8290192dece478caa1dfa4817e1efd283021f6e0 Mon Sep 17 00:00:00 2001 From: nkuehnel Date: Tue, 10 Sep 2024 22:52:47 +0200 Subject: [PATCH 24/27] dvrp: allow fixed dvrp offline travel time estimation --- .../contrib/dvrp/run/DvrpConfigGroup.java | 32 +++++++++++-------- .../DvrpOfflineTravelTimeEstimator.java | 6 ++-- .../DvrpTravelTimeModule.java | 2 +- 3 files changed, 23 insertions(+), 17 deletions(-) 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 25cc051ece8..671b12f8846 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 @@ -19,23 +19,20 @@ package org.matsim.contrib.dvrp.run; -import java.util.Set; - -import javax.annotation.Nullable; - +import jakarta.validation.constraints.DecimalMax; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.PositiveOrZero; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.TransportMode; -import org.matsim.contrib.dynagent.run.DynQSimConfigConsistencyChecker; import org.matsim.contrib.common.util.ReflectiveConfigGroupWithConfigurableParameterSets; +import org.matsim.contrib.dynagent.run.DynQSimConfigConsistencyChecker; import org.matsim.contrib.zone.skims.DvrpTravelTimeMatrixParams; import org.matsim.core.config.Config; -import jakarta.validation.constraints.DecimalMax; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Positive; -import jakarta.validation.constraints.PositiveOrZero; +import javax.annotation.Nullable; +import java.util.Set; public class DvrpConfigGroup extends ReflectiveConfigGroupWithConfigurableParameterSets { private static final Logger log = LogManager.getLogger(DvrpConfigGroup.class); @@ -68,13 +65,14 @@ public static DvrpConfigGroup get(Config config) { @Parameter @Comment("Used for OFFLINE estimation of travel times for VrpOptimizer" + " by means of the exponential moving average." - + " The weighting decrease, alpha, must be in (0,1]." + + " The weighting decrease, alpha, must be in [0,1]." + " We suggest small values of alpha, e.g. 0.05." + " The averaging starts from the initial travel time estimates. If not provided," - + " the free-speed TTs is used as the initial estimates") - @Positive + + " the free-speed TTs is used as the initial estimates. If alpha is set to 0, the initial" + + "travel times stay fixed.") + @PositiveOrZero @DecimalMax("1.0") - public double travelTimeEstimationAlpha = 0.05; // [-], 1 ==> TTs from the last iteration only + public double travelTimeEstimationAlpha = 0.05; // [-], 1 ==> TTs from the last iteration only, 0 ==> initial TTs only @Parameter @Comment("" @@ -146,6 +144,12 @@ protected void checkConsistency(Config config) { if (!config.eventsManager().getSynchronizeOnSimSteps()) { throw new RuntimeException("Synchronization on sim steps is required"); } + if(initialTravelTimesFile == null && travelTimeEstimationAlpha == 0.0) { + throw new RuntimeException("Initial travel times file is required if travel times should not be updated."); + } + if(travelTimeEstimationAlpha == 0.0 && travelTimeEstimationBeta > 0) { + throw new RuntimeException("Online estimation beta should be 0 if travel time should not be updated."); + } } public DvrpTravelTimeMatrixParams getTravelTimeMatrixParams() { diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/trafficmonitoring/DvrpOfflineTravelTimeEstimator.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/trafficmonitoring/DvrpOfflineTravelTimeEstimator.java index 5d80e161462..efd03ff8c0a 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/trafficmonitoring/DvrpOfflineTravelTimeEstimator.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/trafficmonitoring/DvrpOfflineTravelTimeEstimator.java @@ -90,7 +90,7 @@ public DvrpOfflineTravelTimeEstimator(TravelTime initialTT, TravelTime observedT this.delimiter = delimiter; alpha = travelTimeEstimationAlpha; - checkArgument(alpha > 0 && alpha <= 1, "travelTimeEstimationAlpha must be in (0,1]"); + checkArgument(alpha >= 0 && alpha <= 1, "travelTimeEstimationAlpha must be in [0,1]"); linkTravelTimes = DvrpOfflineTravelTimes.convertToLinkTravelTimeMatrix(initialTT, network.getLinks().values(), timeDiscretizer); @@ -114,7 +114,9 @@ private int getIdx(double time) { @Override public void notifyMobsimBeforeCleanup(@SuppressWarnings("rawtypes") MobsimBeforeCleanupEvent e) { - updateTTs(observedTT, alpha); + if(alpha > 0) { + updateTTs(observedTT, alpha); + } } @Override diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/trafficmonitoring/DvrpTravelTimeModule.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/trafficmonitoring/DvrpTravelTimeModule.java index c295c70ac6a..2ac35955346 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/trafficmonitoring/DvrpTravelTimeModule.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/trafficmonitoring/DvrpTravelTimeModule.java @@ -64,7 +64,7 @@ public void install() { addMobsimListenerBinding().to(DvrpOfflineTravelTimeEstimator.class); addControlerListenerBinding().to(DvrpOfflineTravelTimeEstimator.class); - if (dvrpCfg.travelTimeEstimationBeta > 0) {// online estimation + if (dvrpCfg.travelTimeEstimationBeta > 0 && dvrpCfg.travelTimeEstimationAlpha > 0) {// online estimation bind(DvrpOnlineTravelTimeEstimator.class).asEagerSingleton(); addMobsimListenerBinding().to(DvrpOnlineTravelTimeEstimator.class); bind(DvrpTravelTimeEstimator.class).to(DvrpOnlineTravelTimeEstimator.class); From 13b8beb7d70fd5efc29c8c6581f72446339fb989 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Sep 2024 05:52:27 +0000 Subject: [PATCH 25/27] Bump io.grpc:grpc-all from 1.65.1 to 1.66.0 Bumps [io.grpc:grpc-all](https://github.com/grpc/grpc-java) from 1.65.1 to 1.66.0. - [Release notes](https://github.com/grpc/grpc-java/releases) - [Commits](https://github.com/grpc/grpc-java/compare/v1.65.1...v1.66.0) --- updated-dependencies: - dependency-name: io.grpc:grpc-all dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- contribs/hybridsim/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribs/hybridsim/pom.xml b/contribs/hybridsim/pom.xml index b480aa197dd..58663b4a20b 100644 --- a/contribs/hybridsim/pom.xml +++ b/contribs/hybridsim/pom.xml @@ -11,7 +11,7 @@ 4.28.0 - 1.65.1 + 1.66.0 From 2b34584eb6dd2a149ba7de586a9cf1e8f72aa296 Mon Sep 17 00:00:00 2001 From: u229187 Date: Wed, 11 Sep 2024 08:03:09 +0200 Subject: [PATCH 26/27] avoid maven trouble by adding io.opentelemetry-sdk explicitly --- contribs/hybridsim/pom.xml | 141 +++++++++++++++++++------------------ 1 file changed, 73 insertions(+), 68 deletions(-) diff --git a/contribs/hybridsim/pom.xml b/contribs/hybridsim/pom.xml index 58663b4a20b..ac7da45f5b5 100644 --- a/contribs/hybridsim/pom.xml +++ b/contribs/hybridsim/pom.xml @@ -1,77 +1,82 @@ - - org.matsim - contrib - 2025.0-SNAPSHOT - - 4.0.0 - org.matsim.contrib - hybridsim - hybridsim + + org.matsim + contrib + 2025.0-SNAPSHOT + + 4.0.0 + org.matsim.contrib + hybridsim + hybridsim - - 4.28.0 - 1.66.0 - + + 4.28.0 + 1.66.0 + - + - - com.google.protobuf - protobuf-java - ${protobuf.version} - + + com.google.protobuf + protobuf-java + ${protobuf.version} + - - io.grpc - grpc-all - ${grpc.version} - + + io.grpc + grpc-all + ${grpc.version} + - - javax.annotation - javax.annotation-api - 1.3.2 - + + javax.annotation + javax.annotation-api + 1.3.2 + + + io.opentelemetry + opentelemetry-sdk + 1.40.0 + - + - - - - kr.motd.maven - os-maven-plugin - 1.7.1 - - - initialize - - detect - - - - - - org.xolstice.maven.plugins - protobuf-maven-plugin - 0.6.1 - - com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier} - - grpc-java - io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier} - - true - - - - - compile - compile-custom - - - - - - + + + + kr.motd.maven + os-maven-plugin + 1.7.1 + + + initialize + + detect + + + + + + org.xolstice.maven.plugins + protobuf-maven-plugin + 0.6.1 + + com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier} + + grpc-java + io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier} + + true + + + + + compile + compile-custom + + + + + + From c09e8700fe68afb275bc79f33d763e95f9f878db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nico=20K=C3=BChnel?= Date: Wed, 11 Sep 2024 08:53:46 +0200 Subject: [PATCH 27/27] Update DvrpConfigGroup.java --- .../main/java/org/matsim/contrib/dvrp/run/DvrpConfigGroup.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 671b12f8846..306b61d62b3 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 @@ -69,7 +69,7 @@ public static DvrpConfigGroup get(Config config) { + " We suggest small values of alpha, e.g. 0.05." + " The averaging starts from the initial travel time estimates. If not provided," + " the free-speed TTs is used as the initial estimates. If alpha is set to 0, the initial" - + "travel times stay fixed.") + + " travel times stay fixed.") @PositiveOrZero @DecimalMax("1.0") public double travelTimeEstimationAlpha = 0.05; // [-], 1 ==> TTs from the last iteration only, 0 ==> initial TTs only