Skip to content

Commit

Permalink
DrtCompanion with PassengerGroupIdentifier (#3051)
Browse files Browse the repository at this point in the history
* DrtCompanion with PassengerGroupIdentifier

* Minor refactoring, red. public footprint
  • Loading branch information
steffenaxer authored Jan 15, 2024
1 parent 5bab1fd commit b236f2d
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@
import org.matsim.core.scenario.ScenarioUtils;

/**
* @author Steffen Axer
*
* @author steffenaxer
*/
public final class DrtCompanionControlerCreator {

Expand Down
Original file line number Diff line number Diff line change
@@ -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<Id<PassengerGroup>> getGroupId(MobsimPassengerAgent agent) {
Person person = wrapMobsimPassengerAgentToPerson(agent);
return DrtCompanionUtils.getPassengerGroupIdentifier(person);
}

private Person wrapMobsimPassengerAgentToPerson(MobsimPassengerAgent agent)
{
return this.population.getPersons().get(agent.getId());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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))));
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 = ',';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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";
Expand All @@ -58,11 +59,13 @@ public final class DrtCompanionRideGenerator implements BeforeMobsimListener, Af
private final String drtModes;
private final MainModeIdentifier mainModeIdentifier;

private Set<Id<Person>> companionAgentIds = new HashSet<>();
private final Set<Id<Person>> companionAgentIds = new HashSet<>();
private WeightedRandomSelection<Integer> 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;
Expand All @@ -76,40 +79,49 @@ 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<String, Integer> drtCompanionAgents = new HashMap<>();
Collection<Person> companions = new ArrayList<>();
for (Person person : this.scenario.getPopulation().getPersons().values()) {
Id<PassengerGroupIdentifier.PassengerGroup> 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++;
drtCompanionAgents.put(mainMode, currentCounter);
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);
Expand All @@ -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<PassengerGroupIdentifier.PassengerGroup> 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);

Expand All @@ -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<Person> drtCompanion : companionAgentIds) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -72,6 +74,15 @@ public static Integer getAdditionalGroupSize(Person person) {
}
}

public static Optional<Id<PassengerGroupIdentifier.PassengerGroup>> 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;
Expand All @@ -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<PassengerGroupIdentifier.PassengerGroup> passengerGroupIdentifierId ) {
person.getAttributes().putAttribute(GROUP_IDENTIFIER_ATTRIBUTE, passengerGroupIdentifierId);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}
Expand Down

0 comments on commit b236f2d

Please sign in to comment.