-
Notifications
You must be signed in to change notification settings - Fork 141
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
new scoring based on distance groups
- Loading branch information
Showing
12 changed files
with
699 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
72 changes: 72 additions & 0 deletions
72
src/main/java/org/matsim/run/scoring/DetailedPersonScoringParameters.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package org.matsim.run.scoring; | ||
|
||
import com.google.inject.Inject; | ||
import org.matsim.api.core.v01.Scenario; | ||
import org.matsim.api.core.v01.population.Person; | ||
import org.matsim.core.config.ConfigUtils; | ||
import org.matsim.core.config.groups.ScoringConfigGroup; | ||
import org.matsim.core.population.PopulationUtils; | ||
import org.matsim.core.scoring.functions.ActivityUtilityParameters; | ||
import org.matsim.core.scoring.functions.ModeUtilityParameters; | ||
import org.matsim.core.scoring.functions.ScoringParameters; | ||
import org.matsim.core.scoring.functions.ScoringParametersForPerson; | ||
|
||
import java.util.Map; | ||
import java.util.TreeMap; | ||
|
||
public class DetailedPersonScoringParameters implements ScoringParametersForPerson { | ||
|
||
/** | ||
* Cache instances of {@link ActivityUtilityParameters} for each activity type. | ||
* All params are the same for each person. | ||
*/ | ||
private final Map<String, ActivityUtilityParameters> utilParams = new TreeMap<>(); | ||
|
||
/** | ||
* Cache instances of {@link ModeUtilityParameters} for each mode. | ||
*/ | ||
private final Map<String, DistanceGroupModeUtilityParameters> modeParams = new TreeMap<>(); | ||
|
||
@Inject | ||
private Scenario scenario; | ||
|
||
@Override | ||
public ScoringParameters getScoringParameters(Person person) { | ||
|
||
ScoringConfigGroup scoring = scenario.getConfig().scoring(); | ||
String subpopulation = PopulationUtils.getSubpopulation(person); | ||
|
||
ScoringConfigGroup.ScoringParameterSet scoringParameters = scoring.getScoringParameters(subpopulation); | ||
|
||
Map<String, ActivityUtilityParameters> personParams = new TreeMap<>(); | ||
|
||
for (ScoringConfigGroup.ActivityParams params : scoringParameters.getActivityParams()) { | ||
ActivityUtilityParameters p = utilParams.computeIfAbsent(params.getActivityType(), k -> { | ||
ActivityUtilityParameters.Builder factory = new ActivityUtilityParameters.Builder(params); | ||
return factory.build(); | ||
}); | ||
|
||
personParams.put(params.getActivityType(), p); | ||
} | ||
|
||
ScoringParameters.Builder builder = new ScoringParameters.Builder(scoring, scoringParameters, personParams, | ||
scenario.getConfig().scenario()); | ||
|
||
// TODO: not configurable at the moment | ||
if (subpopulation.equals("person")) { | ||
|
||
VspScoringConfigGroup vspScoring = ConfigUtils.addOrGetModule(scenario.getConfig(), VspScoringConfigGroup.class); | ||
|
||
for (Map.Entry<String, VspScoringConfigGroup.ModeParams> e : vspScoring.getModeParams().entrySet()) { | ||
|
||
ModeUtilityParameters params = builder.getModeParameters(e.getKey()); | ||
DistanceGroupModeUtilityParameters p = modeParams.computeIfAbsent(e.getKey(), | ||
k -> new DistanceGroupModeUtilityParameters(params, vspScoring.getDistGroups(), e.getValue())); | ||
|
||
builder.setModeParameters(e.getKey(), p); | ||
} | ||
} | ||
|
||
return builder.build(); | ||
} | ||
} |
88 changes: 88 additions & 0 deletions
88
src/main/java/org/matsim/run/scoring/DistanceGroupModeUtilityParameters.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package org.matsim.run.scoring; | ||
|
||
import org.matsim.core.scoring.functions.ModeUtilityParameters; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.List; | ||
|
||
/** | ||
* Mode utility with separate marginalUtilityOfDistance_m per distance group. | ||
*/ | ||
public class DistanceGroupModeUtilityParameters extends ModeUtilityParameters { | ||
|
||
private final List<DistanceGroup> groups = new ArrayList<>(); | ||
|
||
/** | ||
* Constructor which copies the base params from given modeParams. | ||
*/ | ||
public DistanceGroupModeUtilityParameters(ModeUtilityParameters modeParams, | ||
List<Integer> dists, VspScoringConfigGroup.ModeParams params) { | ||
super(modeParams.marginalUtilityOfTraveling_s, modeParams.marginalUtilityOfDistance_m, modeParams.monetaryDistanceCostRate, | ||
modeParams.constant, modeParams.dailyMoneyConstant, modeParams.dailyUtilityConstant); | ||
|
||
// Nothing to do if no distance groups are defined. | ||
if (dists.isEmpty()) { | ||
return; | ||
} | ||
|
||
List<Integer> copy = new ArrayList<>(dists); | ||
|
||
if (copy.get(0) != 0) | ||
copy.add(0, 0); | ||
|
||
// Effectively no distance groups present | ||
if (copy.size() <= 1) | ||
return; | ||
|
||
for (int i = 0; i < copy.size() - 1; i++) { | ||
|
||
int dist = copy.get(i); | ||
double util = params.getDistUtil(dist).orElseThrow(); | ||
|
||
double constant; | ||
if (i == 0) | ||
constant = 0; | ||
else { | ||
DistanceGroup prev = groups.get(groups.size() - 1); | ||
constant = prev.constant + prev.util_m * (dist - prev.dist); | ||
} | ||
|
||
groups.add(new DistanceGroup(dist, constant, util)); | ||
} | ||
} | ||
|
||
|
||
/** | ||
* Calculate the utility for given distance. | ||
*/ | ||
public double calcDistUtility(double dist) { | ||
|
||
if (groups.isEmpty()) | ||
return marginalUtilityOfDistance_m * dist; | ||
|
||
DistanceGroup group = groups.get(0); | ||
for (int i = 1; i < groups.size(); i++) { | ||
if (groups.get(i).dist > dist) | ||
break; | ||
|
||
group = groups.get(i); | ||
} | ||
|
||
return group.constant + group.util_m * (dist - group.dist); | ||
} | ||
|
||
/** | ||
* Store distance group | ||
* @param dist lower bound for distance group | ||
* @param constant added constant | ||
* @param util_m utility per meter, i.e. slope of linear function | ||
*/ | ||
record DistanceGroup(double dist, double constant, double util_m) implements Comparable<DistanceGroup> { | ||
@Override | ||
public int compareTo(DistanceGroup o) { | ||
return Double.compare(dist, o.dist); | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.