Skip to content

Commit

Permalink
interpret person specific asc as offset in addition to the subpopulat…
Browse files Browse the repository at this point in the history
…ion's asc
  • Loading branch information
vsp-gleich committed Nov 5, 2024
1 parent 613c62d commit de12e72
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
* which is an adoption of {@link org.matsim.core.scoring.functions.SubpopulationScoringParameters}.
* This class additionaly allows for person-specific mode scoring parameters (for now ASC only) and marginalUtilityOfMoney.
* In order to use this, you need to provide the respective attributes (otherwise default values for the subpopulation
* are used). For mode scoring parameters use .... TODO
* are used). The person specific mode parameters are interpreted as offset added to the subpopulation's parameters.
* For marginalUtilityOfMoney an attribute {@link org.matsim.core.population.PersonUtils#getIncome(Person)} for persons that have a specific
* income is used. Persons in the population, that have no attribute {@link org.matsim.core.population.PersonUtils#getIncome(Person)} will use the
* default marginal utility set in their subpopulation's scoring parameters.
Expand Down Expand Up @@ -160,17 +160,18 @@ public ScoringParameters getScoringParameters(Person person) {
Map<String, String> personalScoringModeConstants = PersonUtils.getModeConstants(person);
if (personalScoringModeConstants != null) {
for (Map.Entry<String, String> entry: personalScoringModeConstants.entrySet()) {
ModeUtilityParameters.Builder modeUtilityParamsBuilder = new ModeUtilityParameters.Builder();
ScoringConfigGroup.ModeParams subpopulationModeParams = subpopulationScoringParams.getModes().get(entry.getKey());
ModeUtilityParameters.Builder modeUtilityParamsBuilder = new ModeUtilityParameters.Builder();
try {
modeUtilityParamsBuilder.setConstant(Double.parseDouble(entry.getValue()));
modeUtilityParamsBuilder.setConstant(Double.parseDouble(entry.getValue()) +
subpopulationModeParams.getConstant());
} catch (NumberFormatException e) {
log.error("PersonalScoringModeConstants from person attribute could not be parsed for person " +
person.getId().toString() + ".");
throw new RuntimeException(e);
}

// copy other params from subpopulation config
ScoringConfigGroup.ModeParams subpopulationModeParams = subpopulationScoringParams.getModes().get(entry.getKey());
modeUtilityParamsBuilder.setMarginalUtilityOfTraveling_s(subpopulationModeParams.getMarginalUtilityOfTraveling());
modeUtilityParamsBuilder.setMarginalUtilityOfDistance_m(subpopulationModeParams.getMarginalUtilityOfDistance());
modeUtilityParamsBuilder.setMonetaryDistanceRate(subpopulationModeParams.getMonetaryDistanceRate());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.TransportMode;
import org.matsim.api.core.v01.population.*;
Expand Down Expand Up @@ -50,8 +49,6 @@
*/
public class PersonScoringParametersFromPersonAttributesNoSubpopulationTest {

@RegisterExtension
private MatsimTestUtils utils = new MatsimTestUtils();
private PersonScoringParametersFromPersonAttributes personScoringParams;
private Population population;

Expand Down Expand Up @@ -144,7 +141,7 @@ void testPersonWithLowIncomeLowCarAsc(){
Id<Person> id = Id.createPersonId("lowIncomeLowCarAsc");
ScoringParameters params = personScoringParams.getScoringParameters(population.getPersons().get(id));
makeAssertMarginalUtilityOfMoneyAndPtWait(params, 0.5d, 0.5d);
Assertions.assertEquals(-0.1d, params.modeParams.get(TransportMode.car).constant, MatsimTestUtils.EPSILON);
Assertions.assertEquals(-1.0d -0.1d, params.modeParams.get(TransportMode.car).constant, MatsimTestUtils.EPSILON);
Assertions.assertEquals(-0.001d, params.modeParams.get(TransportMode.car).marginalUtilityOfTraveling_s, MatsimTestUtils.EPSILON);
}

Expand All @@ -153,7 +150,7 @@ void testPersonWithHighIncomeLowCarAsc(){
Id<Person> id = Id.createPersonId("highIncomeLowCarAsc");
ScoringParameters params = personScoringParams.getScoringParameters(population.getPersons().get(id));
makeAssertMarginalUtilityOfMoneyAndPtWait(params, 1.5d, 0.5d);
Assertions.assertEquals(-0.1d, params.modeParams.get(TransportMode.car).constant, MatsimTestUtils.EPSILON);
Assertions.assertEquals(-1.0d -0.1d, params.modeParams.get(TransportMode.car).constant, MatsimTestUtils.EPSILON);
Assertions.assertEquals(-0.001d, params.modeParams.get(TransportMode.car).marginalUtilityOfTraveling_s, MatsimTestUtils.EPSILON);
}

Expand All @@ -162,8 +159,8 @@ void testPersonWithMediumIncomeHighCarAsc(){
Id<Person> id = Id.createPersonId("mediumIncomeHighCarAsc");
ScoringParameters params = personScoringParams.getScoringParameters(population.getPersons().get(id));
makeAssertMarginalUtilityOfMoneyAndPtWait(params, 1d, 0.5d);
Assertions.assertEquals(-2.1d, params.modeParams.get(TransportMode.car).constant, MatsimTestUtils.EPSILON);
Assertions.assertEquals(-50.0d, params.modeParams.get(TransportMode.bike).constant, MatsimTestUtils.EPSILON);
Assertions.assertEquals(-1.0d -2.1d, params.modeParams.get(TransportMode.car).constant, MatsimTestUtils.EPSILON);
Assertions.assertEquals(-0.55d -50.0d, params.modeParams.get(TransportMode.bike).constant, MatsimTestUtils.EPSILON);
Assertions.assertEquals(-0.001d, params.modeParams.get(TransportMode.car).marginalUtilityOfTraveling_s, MatsimTestUtils.EPSILON);
}

Expand All @@ -189,12 +186,12 @@ void testPersonSpecificAscScoring(){
Leg carLegZeroDistanceTenSeconds = createLeg(TransportMode.car, 0.0d, 10.0d );

legScoringRichCarLeg.handleLeg(carLegZeroDistanceTenSeconds);
Assertions.assertEquals(-0.1d -0.001d * 10 -7.5*1./1.5 -0.3, legScoringRichCarLeg.getScore(), MatsimTestUtils.EPSILON, "for the rich person with low car asc, a 0 meter and 10s car trip should be equal to a score of ");
Assertions.assertEquals(-1.0d -0.1d -0.001d * 10 -7.5*1./1.5 -0.3, legScoringRichCarLeg.getScore(), MatsimTestUtils.EPSILON, "for the rich person with low car asc, a 0 meter and 10s car trip should be equal to a score of ");

ScoringParameters paramsMediumIncomeHighCarAsc = personScoringParams.getScoringParameters(population.getPersons().get(Id.createPersonId("mediumIncomeHighCarAsc")));
CharyparNagelLegScoring legScoringMediumIncomeHighCarAsc = new CharyparNagelLegScoring(paramsMediumIncomeHighCarAsc, NetworkUtils.createNetwork(), Set.of(TransportMode.pt));
legScoringMediumIncomeHighCarAsc.handleLeg(carLegZeroDistanceTenSeconds);
Assertions.assertEquals(-2.1d -0.001d * 10 -7.5*1./1.0 -0.3, legScoringMediumIncomeHighCarAsc.getScore(), MatsimTestUtils.EPSILON, "for the medium person with high car asc, a 0 meter and 10s car trip should be equal to a score of ");
Assertions.assertEquals(-1.0d -2.1d -0.001d * 10 -7.5*1./1.0 -0.3, legScoringMediumIncomeHighCarAsc.getScore(), MatsimTestUtils.EPSILON, "for the medium person with high car asc, a 0 meter and 10s car trip should be equal to a score of ");

// bike has no person specific asc for high income person and is not affected
CharyparNagelLegScoring legScoringRichBikeLeg = new CharyparNagelLegScoring(paramsRich, NetworkUtils.createNetwork(), Set.of(TransportMode.pt));
Expand All @@ -205,7 +202,7 @@ void testPersonSpecificAscScoring(){
// bike has a person specific asc for the medium income person
CharyparNagelLegScoring legScoringMediumIncomeBikeLeg = new CharyparNagelLegScoring(paramsMediumIncomeHighCarAsc, NetworkUtils.createNetwork(), Set.of(TransportMode.pt));
legScoringMediumIncomeBikeLeg.handleLeg(bikeLegZeroDistanceZeroSeconds);
Assertions.assertEquals(-50.0d, legScoringMediumIncomeBikeLeg.getScore(), MatsimTestUtils.EPSILON, "for the medium income person with high car asc, a 0 meter and 0s bike trip should be equal to a score of ");
Assertions.assertEquals(-0.55d -50.0d, legScoringMediumIncomeBikeLeg.getScore(), MatsimTestUtils.EPSILON, "for the medium income person with high car asc, a 0 meter and 0s bike trip should be equal to a score of ");
}

private static Leg createLeg(String mode, double distance, double travelTime) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.TransportMode;
import org.matsim.api.core.v01.population.*;
Expand Down Expand Up @@ -50,8 +49,6 @@
*/
public class PersonScoringParametersFromPersonAttributesTest {

@RegisterExtension
private MatsimTestUtils utils = new MatsimTestUtils();
private PersonScoringParametersFromPersonAttributes personScoringParams;
private Population population;

Expand Down Expand Up @@ -166,7 +163,7 @@ void testPersonWithLowIncomeLowCarAsc(){
Id<Person> id = Id.createPersonId("lowIncomeLowCarAsc");
ScoringParameters params = personScoringParams.getScoringParameters(population.getPersons().get(id));
makeAssertMarginalUtilityOfMoneyAndPtWait(params, 0.5d, 0.5d);
Assertions.assertEquals(-0.1d, params.modeParams.get(TransportMode.car).constant, MatsimTestUtils.EPSILON);
Assertions.assertEquals(-1.0d -0.1d, params.modeParams.get(TransportMode.car).constant, MatsimTestUtils.EPSILON);
Assertions.assertEquals(-0.001d, params.modeParams.get(TransportMode.car).marginalUtilityOfTraveling_s, MatsimTestUtils.EPSILON);
}

Expand All @@ -175,7 +172,7 @@ void testPersonWithHighIncomeLowCarAsc(){
Id<Person> id = Id.createPersonId("highIncomeLowCarAsc");
ScoringParameters params = personScoringParams.getScoringParameters(population.getPersons().get(id));
makeAssertMarginalUtilityOfMoneyAndPtWait(params, 1.5d, 0.5d);
Assertions.assertEquals(-0.1d, params.modeParams.get(TransportMode.car).constant, MatsimTestUtils.EPSILON);
Assertions.assertEquals(-1.0d -0.1d, params.modeParams.get(TransportMode.car).constant, MatsimTestUtils.EPSILON);
Assertions.assertEquals(-0.001d, params.modeParams.get(TransportMode.car).marginalUtilityOfTraveling_s, MatsimTestUtils.EPSILON);
}

Expand All @@ -184,8 +181,8 @@ void testPersonWithMediumIncomeHighCarAsc(){
Id<Person> id = Id.createPersonId("mediumIncomeHighCarAsc");
ScoringParameters params = personScoringParams.getScoringParameters(population.getPersons().get(id));
makeAssertMarginalUtilityOfMoneyAndPtWait(params, 1d, 0.5d);
Assertions.assertEquals(-2.1d, params.modeParams.get(TransportMode.car).constant, MatsimTestUtils.EPSILON);
Assertions.assertEquals(-50.0d, params.modeParams.get(TransportMode.bike).constant, MatsimTestUtils.EPSILON);
Assertions.assertEquals(-1.0d -2.1d, params.modeParams.get(TransportMode.car).constant, MatsimTestUtils.EPSILON);
Assertions.assertEquals(-0.55d -50.0d, params.modeParams.get(TransportMode.bike).constant, MatsimTestUtils.EPSILON);
Assertions.assertEquals(-0.001d, params.modeParams.get(TransportMode.car).marginalUtilityOfTraveling_s, MatsimTestUtils.EPSILON);
}

Expand Down Expand Up @@ -229,12 +226,12 @@ void testPersonSpecificAscScoring(){
Leg carLegZeroDistanceTenSeconds = createLeg(TransportMode.car, 0.0d, 10.0d );

legScoringRichCarLeg.handleLeg(carLegZeroDistanceTenSeconds);
Assertions.assertEquals(-0.1d -0.001d * 10 -7.5*1./1.5 -0.3, legScoringRichCarLeg.getScore(), MatsimTestUtils.EPSILON, "for the rich person with low car asc, a 0 meter and 10s car trip should be equal to a score of ");
Assertions.assertEquals(-1.0d -0.1d -0.001d * 10 -7.5*1./1.5 -0.3, legScoringRichCarLeg.getScore(), MatsimTestUtils.EPSILON, "for the rich person with low car asc, a 0 meter and 10s car trip should be equal to a score of ");

ScoringParameters paramsMediumIncomeHighCarAsc = personScoringParams.getScoringParameters(population.getPersons().get(Id.createPersonId("mediumIncomeHighCarAsc")));
CharyparNagelLegScoring legScoringMediumIncomeHighCarAsc = new CharyparNagelLegScoring(paramsMediumIncomeHighCarAsc, NetworkUtils.createNetwork(), Set.of(TransportMode.pt));
legScoringMediumIncomeHighCarAsc.handleLeg(carLegZeroDistanceTenSeconds);
Assertions.assertEquals(-2.1d -0.001d * 10 -7.5*1./1.0 -0.3, legScoringMediumIncomeHighCarAsc.getScore(), MatsimTestUtils.EPSILON, "for the medium person with high car asc, a 0 meter and 10s car trip should be equal to a score of ");
Assertions.assertEquals(-1.0d -2.1d -0.001d * 10 -7.5*1./1.0 -0.3, legScoringMediumIncomeHighCarAsc.getScore(), MatsimTestUtils.EPSILON, "for the medium person with high car asc, a 0 meter and 10s car trip should be equal to a score of ");

// bike has no person specific asc for high income person and is not affected
CharyparNagelLegScoring legScoringRichBikeLeg = new CharyparNagelLegScoring(paramsRich, NetworkUtils.createNetwork(), Set.of(TransportMode.pt));
Expand All @@ -245,7 +242,7 @@ void testPersonSpecificAscScoring(){
// bike has a person specific asc for the medium income person
CharyparNagelLegScoring legScoringMediumIncomeBikeLeg = new CharyparNagelLegScoring(paramsMediumIncomeHighCarAsc, NetworkUtils.createNetwork(), Set.of(TransportMode.pt));
legScoringMediumIncomeBikeLeg.handleLeg(bikeLegZeroDistanceZeroSeconds);
Assertions.assertEquals(-50.0d, legScoringMediumIncomeBikeLeg.getScore(), MatsimTestUtils.EPSILON, "for the medium income person with high car asc, a 0 meter and 0s bike trip should be equal to a score of ");
Assertions.assertEquals(-0.55d -50.0d, legScoringMediumIncomeBikeLeg.getScore(), MatsimTestUtils.EPSILON, "for the medium income person with high car asc, a 0 meter and 0s bike trip should be equal to a score of ");
}

private static Leg createLeg(String mode, double distance, double travelTime) {
Expand Down

0 comments on commit de12e72

Please sign in to comment.