Skip to content

Commit

Permalink
add person filter
Browse files Browse the repository at this point in the history
  • Loading branch information
sebhoerl committed Sep 10, 2024
1 parent 4d6dc1e commit 5816d00
Show file tree
Hide file tree
Showing 10 changed files with 78 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ protected PolicyConfigGroup(String name) {

@Parameter
public boolean active = true;

@Parameter
public String personFilter;
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.eqasim.ile_de_france.policies.transit_discount.TransitDiscountPolicyExtension;
import org.eqasim.ile_de_france.policies.transit_discount.TransitDiscountPolicyFactory;
import org.matsim.api.core.v01.TransportMode;
import org.matsim.api.core.v01.population.Population;
import org.matsim.core.config.Config;
import org.matsim.core.router.costcalculators.OnlyTimeDependentTravelDisutilityFactory;

Expand Down Expand Up @@ -81,7 +82,7 @@ protected void installEqasimExtension() {

@Provides
@Singleton
Map<String, Policy> providePolicies(Map<String, PolicyFactory> factories) {
Map<String, Policy> providePolicies(Map<String, PolicyFactory> factories, Population population) {
PoliciesConfigGroup policyConfig = PoliciesConfigGroup.get(getConfig());
Map<String, Policy> policies = new HashMap<>();

Expand All @@ -100,8 +101,10 @@ Map<String, Policy> providePolicies(Map<String, PolicyFactory> factories) {
throw new IllegalStateException("Duplicate policy name: " + policy.policyName);
}

PolicyPersonFilter filter = PolicyPersonFilter.create(population, policy);

policies.put(policy.policyName,
factories.get(policy.getName()).createPolicy(policy.policyName));
factories.get(policy.getName()).createPolicy(policy.policyName, filter));
}
}
}
Expand Down Expand Up @@ -133,7 +136,6 @@ PolicyUtilityEstimator providePolicyUtilityEstimatorForTransit(Map<String, Provi
}

@Provides
@Singleton
UtilityPenalty provideUtilityPenalty(Map<String, Policy> policies) {
List<UtilityPenalty> penalties = new LinkedList<>();

Expand All @@ -149,7 +151,6 @@ UtilityPenalty provideUtilityPenalty(Map<String, Policy> policies) {
}

@Provides
@Singleton
RoutingPenalty provideRoutingPenalty(Map<String, Policy> policies) {
List<RoutingPenalty> penalties = new LinkedList<>();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package org.eqasim.ile_de_france.policies;

public interface PolicyFactory {
Policy createPolicy(String name);
Policy createPolicy(String name, PolicyPersonFilter personFilter);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.eqasim.ile_de_france.policies;

import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.IdSet;
import org.matsim.api.core.v01.population.Person;
import org.matsim.api.core.v01.population.Population;

public class PolicyPersonFilter {
private final IdSet<Person> selection;

PolicyPersonFilter(IdSet<Person> selection) {
this.selection = selection;
}

public boolean applies(Id<Person> personId) {
return selection == null ? true : selection.contains(personId);
}

static public PolicyPersonFilter create(Population population, PolicyConfigGroup policy) {
if (policy.personFilter != null && policy.personFilter.length() > 0) {
IdSet<Person> selection = new IdSet<>(Person.class);

for (Person person : population.getPersons().values()) {
Boolean indicator = (Boolean) person.getAttributes().getAttribute(policy.personFilter);

if (indicator != null && indicator) {
selection.add(person.getId());
}
}

return new PolicyPersonFilter(selection);
} else {
return new PolicyPersonFilter(null);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.eqasim.ile_de_france.policies.PoliciesConfigGroup;
import org.eqasim.ile_de_france.policies.Policy;
import org.eqasim.ile_de_france.policies.PolicyFactory;
import org.eqasim.ile_de_france.policies.PolicyPersonFilter;
import org.eqasim.ile_de_france.policies.routing.FixedRoutingPenalty;
import org.eqasim.ile_de_france.policies.routing.PolicyLinkFinder;
import org.eqasim.ile_de_france.policies.routing.PolicyLinkFinder.Predicate;
Expand All @@ -34,20 +35,20 @@ public CityTaxPolicyFactory(Config config, Network network, IDFModeParameters mo
}

@Override
public Policy createPolicy(String name) {
public Policy createPolicy(String name, PolicyPersonFilter personFilter) {
for (ConfigGroup item : PoliciesConfigGroup.get(config).getParameterSets(CityTaxPolicyFactory.POLICY_NAME)) {
CityTaxConfigGroup policyItem = (CityTaxConfigGroup) item;

if (policyItem.policyName.equals(name)) {
return createPolicy(policyItem);
return createPolicy(policyItem, personFilter);
}
}

throw new IllegalStateException(
"Configuration not found for policy " + name + " of type " + CityTaxPolicyFactory.POLICY_NAME);
}

private Policy createPolicy(CityTaxConfigGroup enterConfig) {
private Policy createPolicy(CityTaxConfigGroup enterConfig, PolicyPersonFilter personFilter) {
logger.info("Creating policy " + enterConfig.policyName + " of type " + CityTaxPolicyFactory.POLICY_NAME);
logger.info(" Perimeters: " + enterConfig.perimetersPath);
logger.info(" Tax level: " + enterConfig.tax_EUR + " EUR");
Expand All @@ -60,8 +61,8 @@ private Policy createPolicy(CityTaxConfigGroup enterConfig) {
logger.info(" Affected entering links: " + linkIds.size());

return new DefaultPolicy(
new FixedRoutingPenalty(linkIds, calculateEnterTaxPenalty(enterConfig.tax_EUR, modeParameters)),
new CityTaxUtilityPenalty(linkIds, modeParameters, enterConfig.tax_EUR));
new FixedRoutingPenalty(linkIds, calculateEnterTaxPenalty(enterConfig.tax_EUR, modeParameters), personFilter),
new CityTaxUtilityPenalty(linkIds, modeParameters, enterConfig.tax_EUR, personFilter));
}

private double calculateEnterTaxPenalty(double enterTax_EUR, IDFModeParameters parameters) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.List;

import org.eqasim.ile_de_france.mode_choice.parameters.IDFModeParameters;
import org.eqasim.ile_de_france.policies.PolicyPersonFilter;
import org.eqasim.ile_de_france.policies.mode_choice.UtilityPenalty;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.IdSet;
Expand All @@ -18,17 +19,20 @@ public class CityTaxUtilityPenalty implements UtilityPenalty {
private final IDFModeParameters parameters;
private final IdSet<Link> taxedLinkIds;
private final double enterTax_EUR;
private final PolicyPersonFilter personFilter;

public CityTaxUtilityPenalty(IdSet<Link> taxedLinkIds, IDFModeParameters parameters, double enterTax_EUR) {
public CityTaxUtilityPenalty(IdSet<Link> taxedLinkIds, IDFModeParameters parameters, double enterTax_EUR,
PolicyPersonFilter personFilter) {
this.taxedLinkIds = taxedLinkIds;
this.parameters = parameters;
this.enterTax_EUR = enterTax_EUR;
this.personFilter = personFilter;
}

@Override
public double calculatePenalty(String mode, Person person, DiscreteModeChoiceTrip trip,
List<? extends PlanElement> elements) {
if (mode.equals(TransportMode.car)) {
if (mode.equals(TransportMode.car) && personFilter.applies(person.getId())) {
return parameters.betaCost_u_MU * estimateTax_EUR(elements);
} else {
return 0.0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.eqasim.ile_de_france.policies.PoliciesConfigGroup;
import org.eqasim.ile_de_france.policies.Policy;
import org.eqasim.ile_de_france.policies.PolicyFactory;
import org.eqasim.ile_de_france.policies.PolicyPersonFilter;
import org.eqasim.ile_de_france.policies.routing.FixedRoutingPenalty;
import org.eqasim.ile_de_france.policies.routing.PolicyLinkFinder;
import org.eqasim.ile_de_france.policies.routing.PolicyLinkFinder.Predicate;
Expand All @@ -32,21 +33,21 @@ public LimitedTrafficZonePolicyFactory(Config config, Network network) {
}

@Override
public Policy createPolicy(String name) {
public Policy createPolicy(String name, PolicyPersonFilter personFilter) {
for (ConfigGroup item : PoliciesConfigGroup.get(config)
.getParameterSets(LimitedTrafficZonePolicyFactory.POLICY_NAME)) {
LimitedTrafficZoneConfigGroup policyItem = (LimitedTrafficZoneConfigGroup) item;

if (policyItem.policyName.equals(name)) {
return createPolicy(policyItem);
return createPolicy(policyItem, personFilter);
}
}

throw new IllegalStateException("Configuration not found for policy " + name + " of type "
+ LimitedTrafficZonePolicyFactory.POLICY_NAME);
}

private Policy createPolicy(LimitedTrafficZoneConfigGroup ltzConfig) {
private Policy createPolicy(LimitedTrafficZoneConfigGroup ltzConfig, PolicyPersonFilter personFilter) {
logger.info(
"Creating policy " + ltzConfig.policyName + " of type " + LimitedTrafficZonePolicyFactory.POLICY_NAME);
logger.info(" Perimeters: " + ltzConfig.perimetersPath);
Expand All @@ -57,6 +58,6 @@ private Policy createPolicy(LimitedTrafficZoneConfigGroup ltzConfig) {

logger.info(" Affected entering links: " + linkIds.size());

return new DefaultPolicy(new FixedRoutingPenalty(linkIds, enterPenalty), null);
return new DefaultPolicy(new FixedRoutingPenalty(linkIds, enterPenalty, personFilter), null);
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
package org.eqasim.ile_de_france.policies.routing;

import org.eqasim.ile_de_france.policies.PolicyPersonFilter;
import org.matsim.api.core.v01.IdSet;
import org.matsim.api.core.v01.network.Link;
import org.matsim.api.core.v01.population.Person;

public class FixedRoutingPenalty implements RoutingPenalty {
private final IdSet<Link> linkIds;
private final double penalty;
private final PolicyPersonFilter personFilter;

public FixedRoutingPenalty(IdSet<Link> linkIds, double penalty) {
public FixedRoutingPenalty(IdSet<Link> linkIds, double penalty, PolicyPersonFilter personFilter) {
this.linkIds = linkIds;
this.penalty = penalty;
this.personFilter = personFilter;
}

@Override
public double getLinkPenalty(Link link, Person person, double time) {
return linkIds.contains(link.getId()) ? penalty : 0.0;
return linkIds.contains(link.getId()) && personFilter.applies(person.getId()) ? penalty : 0.0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.eqasim.ile_de_france.policies.PoliciesConfigGroup;
import org.eqasim.ile_de_france.policies.Policy;
import org.eqasim.ile_de_france.policies.PolicyFactory;
import org.eqasim.ile_de_france.policies.PolicyPersonFilter;
import org.matsim.core.config.Config;
import org.matsim.core.config.ConfigGroup;

Expand All @@ -27,26 +28,26 @@ public TransitDiscountPolicyFactory(Config config, CostModel costModel, IDFModeP
}

@Override
public Policy createPolicy(String name) {
public Policy createPolicy(String name, PolicyPersonFilter personFilter) {
for (ConfigGroup item : PoliciesConfigGroup.get(config)
.getParameterSets(TransitDiscountPolicyFactory.POLICY_NAME)) {
TransitDiscountConfigGroup policyItem = (TransitDiscountConfigGroup) item;

if (policyItem.policyName.equals(name)) {
return createPolicy(policyItem);
return createPolicy(policyItem, personFilter);
}
}

throw new IllegalStateException(
"Configuration not found for policy " + name + " of type " + TransitDiscountPolicyFactory.POLICY_NAME);
}

private Policy createPolicy(TransitDiscountConfigGroup discountConfig) {
private Policy createPolicy(TransitDiscountConfigGroup discountConfig, PolicyPersonFilter personFilter) {
logger.info("Creating policy " + discountConfig.policyName + " of type "
+ TransitDiscountPolicyFactory.POLICY_NAME);
logger.info(" Price factor: " + discountConfig.priceFactor);

return new DefaultPolicy(null,
new TransitDiscountUtilityPenalty(costModel, modeParameters, discountConfig.priceFactor));
new TransitDiscountUtilityPenalty(costModel, modeParameters, discountConfig.priceFactor, personFilter));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import org.eqasim.core.simulation.mode_choice.cost.CostModel;
import org.eqasim.ile_de_france.mode_choice.parameters.IDFModeParameters;
import org.eqasim.ile_de_france.policies.PolicyPersonFilter;
import org.eqasim.ile_de_france.policies.mode_choice.UtilityPenalty;
import org.matsim.api.core.v01.TransportMode;
import org.matsim.api.core.v01.population.Person;
Expand All @@ -14,17 +15,20 @@ public class TransitDiscountUtilityPenalty implements UtilityPenalty {
private final CostModel costModel;
private final IDFModeParameters modeParameters;
private final double costFactor;
private final PolicyPersonFilter personFilter;

public TransitDiscountUtilityPenalty(CostModel costModel, IDFModeParameters modeParameters, double costFactor) {
public TransitDiscountUtilityPenalty(CostModel costModel, IDFModeParameters modeParameters, double costFactor,
PolicyPersonFilter personFilter) {
this.costModel = costModel;
this.modeParameters = modeParameters;
this.costFactor = costFactor;
this.personFilter = personFilter;
}

@Override
public double calculatePenalty(String mode, Person person, DiscreteModeChoiceTrip trip,
List<? extends PlanElement> elements) {
if (mode.equals(TransportMode.pt)) {
if (mode.equals(TransportMode.pt) && personFilter.applies(person.getId())) {
double initialCost = costModel.calculateCost_MU(person, trip, elements);
double updatedCost = initialCost * costFactor;
return modeParameters.betaCost_u_MU * (updatedCost - initialCost);
Expand Down

0 comments on commit 5816d00

Please sign in to comment.