From b236f2d31eccb69f6318562f47c3a441ed477dcc Mon Sep 17 00:00:00 2001 From: "Dr. Steffen Axer" <26229392+steffenaxer@users.noreply.github.com> Date: Mon, 15 Jan 2024 17:51:52 +0100 Subject: [PATCH] DrtCompanion with PassengerGroupIdentifier (#3051) * DrtCompanion with PassengerGroupIdentifier * Minor refactoring, red. public footprint --- .../DrtCompanionControlerCreator.java | 3 +- .../DrtCompanionGroupIdentifier.java | 51 +++++++++++++++++++ .../companions/DrtCompanionModule.java | 30 +++++++---- .../companions/DrtCompanionParams.java | 4 +- .../companions/DrtCompanionRideGenerator.java | 41 ++++++++++----- .../companions/DrtCompanionUtils.java | 21 ++++++-- .../MultiModeDrtCompanionModule.java | 15 ++---- 7 files changed, 122 insertions(+), 43 deletions(-) create mode 100644 contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionGroupIdentifier.java diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionControlerCreator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionControlerCreator.java index 058588cf40e..4e8659df037 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionControlerCreator.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionControlerCreator.java @@ -32,8 +32,7 @@ import org.matsim.core.scenario.ScenarioUtils; /** - * @author Steffen Axer - * + * @author steffenaxer */ public final class DrtCompanionControlerCreator { diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionGroupIdentifier.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionGroupIdentifier.java new file mode 100644 index 00000000000..bd3f4445f92 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionGroupIdentifier.java @@ -0,0 +1,51 @@ +/* *********************************************************************** * + * project: org.matsim.* + * * + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** */ + +package org.matsim.contrib.drt.extension.companions; + +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.population.Person; +import org.matsim.api.core.v01.population.Population; +import org.matsim.contrib.dvrp.passenger.PassengerGroupIdentifier; +import org.matsim.core.mobsim.framework.MobsimPassengerAgent; + +import java.util.Optional; + +/** + * @author steffenaxer + */ +class DrtCompanionGroupIdentifier implements PassengerGroupIdentifier { + private final Population population; + DrtCompanionGroupIdentifier(final Population population) + { + this.population = population; + } + + @Override + public Optional> getGroupId(MobsimPassengerAgent agent) { + Person person = wrapMobsimPassengerAgentToPerson(agent); + return DrtCompanionUtils.getPassengerGroupIdentifier(person); + } + + private Person wrapMobsimPassengerAgentToPerson(MobsimPassengerAgent agent) + { + return this.population.getPersons().get(agent.getId()); + } + +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionModule.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionModule.java index f93d49b19a6..b9fee55c454 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionModule.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionModule.java @@ -20,37 +20,45 @@ package org.matsim.contrib.drt.extension.companions; import org.matsim.api.core.v01.Scenario; -import org.matsim.api.core.v01.network.Network; +import org.matsim.api.core.v01.population.Population; import org.matsim.contrib.drt.extension.DrtWithExtensionsConfigGroup; +import org.matsim.contrib.dvrp.passenger.PassengerGroupIdentifier; import org.matsim.contrib.dvrp.run.AbstractDvrpModeModule; +import org.matsim.contrib.dvrp.run.AbstractDvrpModeQSimModule; import org.matsim.core.router.MainModeIdentifier; + /** * This module samples additional drt rides on booked drt trips in order to * replicate a more realistic vehicle occupancy. * * @author Steffen Axer - * */ public class DrtCompanionModule extends AbstractDvrpModeModule { - DrtWithExtensionsConfigGroup drtWithExtensionsConfigGroup; + final DrtWithExtensionsConfigGroup drtWithExtensionsConfigGroup; - public DrtCompanionModule(String mode, DrtWithExtensionsConfigGroup drtWithExtensionsConfigGroup) { + public DrtCompanionModule(final String mode, final DrtWithExtensionsConfigGroup drtWithExtensionsConfigGroup) { super(mode); this.drtWithExtensionsConfigGroup = drtWithExtensionsConfigGroup; - } @Override public void install() { bindModal(DrtCompanionRideGenerator.class).toProvider( modalProvider(getter -> new DrtCompanionRideGenerator( - getMode(), // - getter.get(MainModeIdentifier.class), // - getter.get(Scenario.class), // - getter.getModal(Network.class), // - this.drtWithExtensionsConfigGroup))) - .asEagerSingleton(); + getMode(), // + getter.get(MainModeIdentifier.class), // + getter.get(Scenario.class), // + this.drtWithExtensionsConfigGroup))) + .asEagerSingleton(); addControlerListenerBinding().to(modalKey(DrtCompanionRideGenerator.class)); + installOverridingQSimModule(new AbstractDvrpModeQSimModule(getMode()) { + @Override + protected void configureQSim() { + bindModal(PassengerGroupIdentifier.class).toProvider( + modalProvider(getter -> new DrtCompanionGroupIdentifier( + getter.get(Population.class)))); + } + }); } } diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionParams.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionParams.java index 3789be3449c..f3947244027 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionParams.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionParams.java @@ -28,9 +28,7 @@ import org.matsim.core.utils.misc.StringUtils; /** - * - * @author Steffen Axer - * + * @author steffenaxer */ public class DrtCompanionParams extends ReflectiveConfigGroupWithConfigurableParameterSets { private static final char DEFAULT_COLLECTION_DELIMITER = ','; diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionRideGenerator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionRideGenerator.java index 66f552ee730..6b841cd0a75 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionRideGenerator.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionRideGenerator.java @@ -36,6 +36,7 @@ import org.matsim.api.core.v01.population.Plan; import org.matsim.contrib.drt.extension.DrtWithExtensionsConfigGroup; import org.matsim.contrib.common.util.WeightedRandomSelection; +import org.matsim.contrib.dvrp.passenger.PassengerGroupIdentifier; import org.matsim.core.controler.events.AfterMobsimEvent; import org.matsim.core.controler.events.BeforeMobsimEvent; import org.matsim.core.controler.listener.AfterMobsimListener; @@ -48,7 +49,7 @@ /** * @author Steffen Axer */ -public final class DrtCompanionRideGenerator implements BeforeMobsimListener, AfterMobsimListener { +final class DrtCompanionRideGenerator implements BeforeMobsimListener, AfterMobsimListener { private static final Logger LOG = LogManager.getLogger(DrtCompanionRideGenerator.class); public final static String DRT_COMPANION_AGENT_PREFIX = "COMPANION"; @@ -58,11 +59,13 @@ public final class DrtCompanionRideGenerator implements BeforeMobsimListener, Af private final String drtModes; private final MainModeIdentifier mainModeIdentifier; - private Set> companionAgentIds = new HashSet<>(); + private final Set> companionAgentIds = new HashSet<>(); private WeightedRandomSelection sampler; + private int passengerGroupIdentifier = 0; // Should be unique over the entire simulation + DrtCompanionRideGenerator(final String drtMode, final MainModeIdentifier mainModeIdentifier, - final Scenario scenario, final Network network, + final Scenario scenario, final DrtWithExtensionsConfigGroup drtWithExtensionsConfigGroup) { this.scenario = scenario; this.mainModeIdentifier = mainModeIdentifier; @@ -76,27 +79,34 @@ private String getCompanionPrefix(String drtMode) { private void installSampler(DrtWithExtensionsConfigGroup drtWithExtensionsConfigGroup) { if (!drtWithExtensionsConfigGroup.getDrtCompanionParams().orElseThrow().getDrtCompanionSamplingWeights() - .isEmpty()) { + .isEmpty()) { this.sampler = DrtCompanionUtils.createIntegerSampler( - drtWithExtensionsConfigGroup.getDrtCompanionParams().orElseThrow() - .getDrtCompanionSamplingWeights()); + drtWithExtensionsConfigGroup.getDrtCompanionParams().orElseThrow() + .getDrtCompanionSamplingWeights()); } else { throw new IllegalStateException( - "drtCompanionSamplingWeights are empty, please check your DrtCompanionParams"); + "drtCompanionSamplingWeights are empty, please check your DrtCompanionParams"); } } - void addCompanionAgents() { - int identifier = 0; + private void addCompanionAgents() { + int personIdentifierSuffix = 0; HashMap drtCompanionAgents = new HashMap<>(); Collection companions = new ArrayList<>(); for (Person person : this.scenario.getPopulation().getPersons().values()) { + Id passengerGroupIdentifierId = Id.create(this.passengerGroupIdentifier, PassengerGroupIdentifier.PassengerGroup.class); for (TripStructureUtils.Trip trip : TripStructureUtils.getTrips(person.getSelectedPlan())) { String mainMode = mainModeIdentifier.identifyMainMode(trip.getTripElements()); if (this.drtModes.equals(mainMode)) { int additionalCompanions = sampler.select(); + if(additionalCompanions>0) + { + // Initial person travels now in a group + DrtCompanionUtils.setPassengerGroupIdentifier(person, passengerGroupIdentifierId); + } + for (int i = 0; i < additionalCompanions; i++) { int currentCounter = drtCompanionAgents.getOrDefault(mainMode, 0); currentCounter++; @@ -104,12 +114,14 @@ void addCompanionAgents() { int groupSize = additionalCompanions + 1; int groupPart = i; + // Bypass passengerGroupIdentifierId to each group member companions.add(createCompanionAgent(mainMode, person, trip, trip.getOriginActivity(), - trip.getDestinationActivity(), groupPart, groupSize, identifier)); - identifier++; + trip.getDestinationActivity(), groupPart, groupSize, personIdentifierSuffix, passengerGroupIdentifierId)); + personIdentifierSuffix++; } } } + passengerGroupIdentifier++; } companions.forEach(p -> { this.scenario.getPopulation().addPerson(p); @@ -122,9 +134,9 @@ void addCompanionAgents() { } private Person createCompanionAgent(String drtMode, Person originalPerson, TripStructureUtils.Trip trip, - Activity fromActivity, Activity toActivity, int groupPart, int groupSize, int identifier) { + Activity fromActivity, Activity toActivity, int groupPart, int groupSize, int personIdentifier, Id passengerGroupIdentifierId) { String prefix = getCompanionPrefix(drtMode); - String companionId = prefix + "_" + originalPerson.getId().toString() + "_" + identifier; + String companionId = prefix + "_" + originalPerson.getId().toString() + "_" + personIdentifier; Person person = PopulationUtils.getFactory().createPerson(Id.createPersonId(companionId)); DrtCompanionUtils.setDRTCompanionType(person, DRT_COMPANION_TYPE); @@ -147,11 +159,12 @@ private Person createCompanionAgent(String drtMode, Person originalPerson, TripS // Add group information to trip DrtCompanionUtils.setAdditionalGroupPart(person, groupPart); DrtCompanionUtils.setAdditionalGroupSize(person, groupSize); + DrtCompanionUtils.setPassengerGroupIdentifier(person, passengerGroupIdentifierId); return person; } - void removeCompanionAgents() { + private void removeCompanionAgents() { int counter = 0; for (Id drtCompanion : companionAgentIds) { diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionUtils.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionUtils.java index 4f9d6e33317..682d171814b 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionUtils.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionUtils.java @@ -20,21 +20,23 @@ package org.matsim.contrib.drt.extension.companions; import java.util.List; +import java.util.Optional; +import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.population.Person; import org.matsim.contrib.common.util.WeightedRandomSelection; +import org.matsim.contrib.dvrp.passenger.PassengerGroupIdentifier; import org.matsim.core.gbl.MatsimRandom; /** - * - * @author Steffen Axer - * + * @author steffenaxer */ public class DrtCompanionUtils { public final static String ADDITIONAL_GROUP_SIZE_ATTRIBUTE = "additionalGroupSize"; public final static String ADDITIONAL_GROUP_PART_ATTRIBUTE = "additionalGroupPart"; public static final String COMPANION_TYPE_ATTRIBUTE = "companionType"; + public static final String GROUP_IDENTIFIER_ATTRIBUTE = "groupIdentifier"; private DrtCompanionUtils() { throw new IllegalStateException("Utility class"); @@ -72,6 +74,15 @@ public static Integer getAdditionalGroupSize(Person person) { } } + public static Optional> getPassengerGroupIdentifier(Person person) { + if (person.getAttributes().getAttribute(GROUP_IDENTIFIER_ATTRIBUTE) == null) { + return Optional.empty(); + } else { + return Optional.of(Id.create(person.getAttributes() + .getAttribute(GROUP_IDENTIFIER_ATTRIBUTE).toString(), PassengerGroupIdentifier.PassengerGroup.class)); + } + } + public static Integer getAdditionalGroupPart(Person person) { if (person.getAttributes().getAttribute(ADDITIONAL_GROUP_PART_ATTRIBUTE) == null) { return null; @@ -88,4 +99,8 @@ public static void setAdditionalGroupPart(Person person, int additionalgroupPart person.getAttributes().putAttribute(ADDITIONAL_GROUP_PART_ATTRIBUTE, additionalgroupPart); } + public static void setPassengerGroupIdentifier(Person person, Id passengerGroupIdentifierId ) { + person.getAttributes().putAttribute(GROUP_IDENTIFIER_ATTRIBUTE, passengerGroupIdentifierId); + } + } diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/MultiModeDrtCompanionModule.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/MultiModeDrtCompanionModule.java index 2ca26b70f32..599636b04d6 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/MultiModeDrtCompanionModule.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/MultiModeDrtCompanionModule.java @@ -19,27 +19,22 @@ package org.matsim.contrib.drt.extension.companions; +import com.google.inject.Inject; import org.matsim.contrib.drt.extension.DrtWithExtensionsConfigGroup; import org.matsim.contrib.drt.run.DrtConfigGroup; import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; import org.matsim.core.controler.AbstractModule; -import com.google.inject.Inject; - /** - * - * @author Steffen Axer - * + * @author steffenaxer */ public class MultiModeDrtCompanionModule extends AbstractModule { - @Inject - private MultiModeDrtConfigGroup multiModeDrtCfg; - @Override public void install() { + MultiModeDrtConfigGroup multiModeDrtCfg = MultiModeDrtConfigGroup.get(getConfig()); for (DrtConfigGroup drtCfg : multiModeDrtCfg.getModalElements()) { - if (drtCfg instanceof DrtWithExtensionsConfigGroup && ((DrtWithExtensionsConfigGroup) drtCfg).getDrtCompanionParams().isPresent()) { - DrtWithExtensionsConfigGroup drtWithExtensionsConfigGroup = (DrtWithExtensionsConfigGroup) drtCfg; + if (drtCfg instanceof DrtWithExtensionsConfigGroup drtWithExtensionsConfigGroup && ((DrtWithExtensionsConfigGroup) drtCfg).getDrtCompanionParams().isPresent()) { + drtWithExtensionsConfigGroup = (DrtWithExtensionsConfigGroup) drtCfg; install(new DrtCompanionModule(drtCfg.getMode(), drtWithExtensionsConfigGroup)); } }