diff --git a/contribs/accessibility/pom.xml b/contribs/accessibility/pom.xml
index 300f8fb1bd1..c8eab124745 100644
--- a/contribs/accessibility/pom.xml
+++ b/contribs/accessibility/pom.xml
@@ -83,5 +83,17 @@
gt-jdbc-postgis
${geotools.version}
+
+ org.matsim.contrib
+ dvrp
+ 16.0-SNAPSHOT
+ compile
+
+
+ org.matsim.contrib
+ drt
+ 16.0-SNAPSHOT
+ compile
+
diff --git a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/AccessibilityModule.java b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/AccessibilityModule.java
index 459198164a4..7acd374f3e0 100644
--- a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/AccessibilityModule.java
+++ b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/AccessibilityModule.java
@@ -159,9 +159,10 @@ public ControlerListener get() {
} else if ( TransportMode.pt.equals( mode ) ){
calculator = new SwissRailRaptorAccessibilityContributionCalculator( mode, config.scoring(), scenario );
} else if ( Modes4Accessibility.estimatedDrt.name().equals( mode )) {
- final TravelTime travelTime = travelTimes.get(TransportMode.drt);
- final TravelDisutilityFactory travelDisutilityFactory = travelDisutilityFactories.get(TransportMode.drt);
- calculator = new EstimatedDrtAccessibilityContributionCalculator(mode, travelTime, travelDisutilityFactory, scenario);
+// final TravelTime travelTime = travelTimes.get("dvrp_estimated"); //TODO
+ final TravelTime travelTime = travelTimes.get(TransportMode.car); //TODO
+ final TravelDisutilityFactory travelDisutilityFactory = travelDisutilityFactories.get(TransportMode.car); //TODO
+ calculator = new EstimatedDrtAccessibilityContributionCalculator(mode, travelTime, travelDisutilityFactory, scenario, tripRouter);
} else if ( Modes4Accessibility.matrixBasedPt.name().equals( mode ) ) {
throw new RuntimeException("currently not supported because implementation not consistent with guice grapher. kai, sep'19") ;
// calculator = new LeastCostPathCalculatorAccessibilityContributionCalculator(
diff --git a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/EstimatedDrtAccessibilityContributionCalculator.java b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/EstimatedDrtAccessibilityContributionCalculator.java
index 532e4f6a834..bad2e6abbb3 100644
--- a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/EstimatedDrtAccessibilityContributionCalculator.java
+++ b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/EstimatedDrtAccessibilityContributionCalculator.java
@@ -1,21 +1,26 @@
package org.matsim.contrib.accessibility;
-import com.google.common.collect.ImmutableMap;
+import org.apache.commons.lang3.tuple.Pair;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
-import org.matsim.api.core.v01.BasicLocation;
-import org.matsim.api.core.v01.Id;
-import org.matsim.api.core.v01.Scenario;
-import org.matsim.api.core.v01.TransportMode;
-import org.matsim.api.core.v01.network.Link;
+import org.matsim.api.core.v01.*;
import org.matsim.api.core.v01.network.Network;
import org.matsim.api.core.v01.network.Node;
+import org.matsim.api.core.v01.population.Leg;
+import org.matsim.api.core.v01.population.Person;
+import org.matsim.api.core.v01.population.PlanElement;
import org.matsim.contrib.accessibility.utils.*;
+import org.matsim.contrib.drt.routing.DrtStopFacility;
+import org.matsim.contrib.dvrp.router.DvrpRoutingModule;
+import org.matsim.core.config.Config;
+import org.matsim.core.config.ConfigUtils;
import org.matsim.core.config.groups.NetworkConfigGroup;
import org.matsim.core.config.groups.ScoringConfigGroup;
import org.matsim.core.gbl.Gbl;
import org.matsim.core.network.NetworkUtils;
import org.matsim.core.network.algorithms.TransportModeNetworkFilter;
+import org.matsim.core.population.PopulationUtils;
+import org.matsim.core.router.*;
import org.matsim.core.router.costcalculators.TravelDisutilityFactory;
import org.matsim.core.router.speedy.SpeedyALTFactory;
import org.matsim.core.router.util.LeastCostPathCalculator;
@@ -23,8 +28,12 @@
import org.matsim.core.router.util.TravelTime;
import org.matsim.facilities.ActivityFacilities;
import org.matsim.facilities.ActivityFacility;
+import org.matsim.facilities.Facility;
+import org.matsim.matrices.Entry;
+import org.matsim.pt.transitSchedule.api.TransitStopFacility;
import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
/**
* @author thibautd, dziemke
@@ -43,9 +52,10 @@ final class EstimatedDrtAccessibilityContributionCalculator implements Accessibi
private Network subNetwork;
- private final double betaWalkTT;
+ private final double betaWalkTT_h;
- private final double betaDrtTT;
+ private final double betaDrtTT_h;
+ private final double betaDrtDist_m;
private final double walkSpeed_m_s;
private Node fromNode = null;
@@ -54,27 +64,28 @@ final class EstimatedDrtAccessibilityContributionCalculator implements Accessibi
private Map, AggregationObject> aggregatedOpportunities;
private final LeastCostPathCalculator router;
+ TripRouter tripRouter ;// TODO: this Getter is a temporary hack. Talk to TS about other ways of accessing the stopFinder
+ private DvrpRoutingModule.AccessEgressFacilityFinder stopFinder;
-
- public EstimatedDrtAccessibilityContributionCalculator(String mode, final TravelTime travelTime, final TravelDisutilityFactory travelDisutilityFactory, Scenario scenario) {
+ public EstimatedDrtAccessibilityContributionCalculator(String mode, final TravelTime travelTime, final TravelDisutilityFactory travelDisutilityFactory, Scenario scenario, TripRouter tripRouter) {
this.mode = mode;
this.travelTime = travelTime;
this.travelDisutilityFactory = travelDisutilityFactory;
this.scenario = scenario;
this.scoringConfigGroup = scenario.getConfig().scoring();
this.networkConfigGroup = scenario.getConfig().network();
+ this.tripRouter = tripRouter;
Gbl.assertNotNull(travelDisutilityFactory);
this.travelDisutility = travelDisutilityFactory.createTravelDisutility(travelTime);
this.router = new SpeedyALTFactory().createPathCalculator(scenario.getNetwork(), travelDisutility, travelTime);
-
-
- betaWalkTT = scoringConfigGroup.getModes().get(TransportMode.walk).getMarginalUtilityOfTraveling() - scoringConfigGroup.getPerforming_utils_hr();
- betaDrtTT = scoringConfigGroup.getModes().get(TransportMode.drt).getMarginalUtilityOfTraveling() - scoringConfigGroup.getPerforming_utils_hr();
-
+ betaWalkTT_h = scoringConfigGroup.getModes().get(TransportMode.walk).getMarginalUtilityOfTraveling() - scoringConfigGroup.getPerforming_utils_hr();
+ betaDrtTT_h = scoringConfigGroup.getModes().get(TransportMode.drt).getMarginalUtilityOfTraveling() - scoringConfigGroup.getPerforming_utils_hr();
+ betaDrtDist_m = scoringConfigGroup.getModes().get(TransportMode.drt).getMarginalUtilityOfDistance();
this.walkSpeed_m_s = scenario.getConfig().routing().getTeleportedModeSpeeds().get(TransportMode.walk);
+ stopFinder = ((DvrpRoutingModule) tripRouter.getRoutingModule(TransportMode.drt)).getStopFinder();// todo
// this.drtEstimator = new EuclideanDistanceBasedDrtEstimator(scenario.getNetwork(), 1.2, 0.0842928, 337.1288522, 5 * 60, 0, 0, 0);
// this.drtEstimator = DetourBasedDrtEstimator.normalDistributed(337.1288522, 0.0842928, 0., 0. * 60, 0);
@@ -85,6 +96,9 @@ public EstimatedDrtAccessibilityContributionCalculator(String mode, final Travel
@Override
public void initialize(ActivityFacilities measuringPoints, ActivityFacilities opportunities) {
+
+
+
LOG.warn("Initializing calculator for mode " + mode + "...");
LOG.warn("Full network has " + scenario.getNetwork().getNodes().size() + " nodes.");
subNetwork = NetworkUtils.createNetwork(networkConfigGroup);
@@ -98,7 +112,10 @@ public void initialize(ActivityFacilities measuringPoints, ActivityFacilities op
LOG.warn("sub-network for mode " + modeSet + " now has " + subNetwork.getNodes().size() + " nodes.");
this.aggregatedMeasurePoints = AccessibilityUtils.aggregateMeasurePointsWithSameNearestNode(measuringPoints, subNetwork);
- this.aggregatedOpportunities = AccessibilityUtils.aggregateOpportunitiesWithSameNearestNode(opportunities, subNetwork, scenario.getConfig());
+// this.aggregatedOpportunities = AccessibilityUtils.aggregateOpportunitiesWithSameNearestNode(opportunities, subNetwork, scenario.getConfig());
+
+// this.aggregatedMeasurePoints = measuringPoints;
+ this.aggregatedOpportunities = aggregateOpportunitiesWithSameNearestDrtStop(opportunities, subNetwork, scenario.getConfig());
}
@@ -117,64 +134,54 @@ public double computeContributionOfOpportunity(ActivityFacility origin,
Map, AggregationObject> aggregatedOpportunities, Double departureTime) {
double expSum = 0.;
+ Optional> facilities = stopFinder.findFacilities(origin, origin, null); //todo: cleanup
+ Facility nearestStopAccess = facilities.get().getKey();
- // Access
-// new ClosestAccessEgressFacilityFinder(2000, scenario.getNetwork(), facilityQuadTree);
-
- // DRT Trip
+ List extends PlanElement> planElementsAccess = tripRouter.calcRoute(TransportMode.walk, origin, nearestStopAccess, departureTime, null, null);
+ double accessTime_h = ((Leg) planElementsAccess.get(0)).getTravelTime().seconds() / 3600;
- // Egress
+ double utility_access = accessTime_h * betaWalkTT_h;
+ double utilityDrtConstant = AccessibilityUtils.getModeSpecificConstantForAccessibilities(TransportMode.drt, scoringConfigGroup);
- // Old Approach: nearest link...
- Link nearestLink = NetworkUtils.getNearestLinkExactly(subNetwork, origin.getCoord());
- Distances distance = NetworkUtil.getDistances2NodeViaGivenLink(origin.getCoord(), nearestLink, fromNode);
- double walkTravelTimeMeasuringPoint2Road_h = distance.getDistancePoint2Intersection() / (this.walkSpeed_m_s * 3600);
- // Orthogonal walk to nearest link
- double walkUtilityMeasuringPoint2Road = (walkTravelTimeMeasuringPoint2Road_h * betaWalkTT);
- // Travel on section of first link to first node
- double distanceFraction = distance.getDistanceIntersection2Node() / nearestLink.getLength();
- double congestedCarUtilityRoad2Node = -travelDisutility.getLinkTravelDisutility(nearestLink, departureTime, null, null) * distanceFraction;
- // Combine all utility components (using the identity: exp(a+b) = exp(a) * exp(b))
- double modeSpecificConstant = AccessibilityUtils.getModeSpecificConstantForAccessibilities(TransportMode.drt, scoringConfigGroup); // TODO: update from car to drt
+ for (AggregationObject destination : aggregatedOpportunities.values()) {
- for (final AggregationObject destination : aggregatedOpportunities.values()) {
+ // Calculate main drt leg:
+ Facility nearestStopEgress = (Facility) destination.getNearestBasicLocation();
- // utility during DRT ride
-// DrtEstimator.Estimate estimate = drtEstimator.estimate(origin.getCoord(), destination.getNearestBasicLocation().getCoord(), OptionalTime.defined(departureTime));
+ // Doesn't work because we need a person... //TODO: replace actual person with a fake person, or find workaround.
+ List extends PlanElement> planElementsMain = tripRouter.calcRoute(TransportMode.car, nearestStopAccess, nearestStopEgress, 10 * 3600, scenario.getPopulation().getPersons().get(Id.createPersonId("1213")), null);
-// DrtRoute route = new DrtRoute(Id.createLinkId("xxx"), Id.createLinkId("yyy"));
+ double directRideDistance_m = ((Leg) planElementsMain.get(2)).getRoute().getDistance();
- Node destinationNode = (Node) destination.getNearestBasicLocation();
-// double directRideTime = VrpPaths.calcAndCreatePath(nearestLink, toLink, departureTime, router, travelTime).getTravelTime();
-// LeastCostPathCalculator.Path vrpPath = router.calcLeastCostPath(nearestLink.getToNode(), toLink.getFromNode(), departureTime, null, null);
- LeastCostPathCalculator.Path vrpPath = router.calcLeastCostPath(nearestLink.getToNode(), destinationNode, departureTime, null, null);
- List links = vrpPath.links;
-// links.add(toLink); TODO: do we need this?
- double directRideDistance = links.stream().mapToDouble(Link::getLength).sum();
+ double waitTime_s = 103.34; //TODO
+ double rideTime_s = 47.84 + 0.1087 * directRideDistance_m;
+ double totalTime_h = (waitTime_s + rideTime_s) / 3600;
+ double utilityDrtTime = betaDrtTT_h * totalTime_h;
+ double utilityDrtDistance = betaDrtDist_m * directRideDistance_m;
-// route.setDirectRideTime(directRideTime);
-// route.setDistance(directRideDistance);
-// route.setStartLinkId(nearestLink.getId());
-// route.setEndLinkId(toLink.getId());
-// DrtEstimator.Estimate estimate = drtEstimator.estimate(route, OptionalTime.defined(departureTime));
- double waitTime = 103.34;
- double rideTime = 47.84 + 0.1087 * directRideDistance;
- double totalTime = (waitTime + rideTime) / 3600;
- double utilityDrt = betaDrtTT * totalTime;
// Pre-computed effect of all opportunities reachable from destination network node
double sumExpVjkWalk = destination.getSum();
+
+ System.out.println("___________________________________");
+ System.out.println("Measuring Point: " + origin.getId().toString());
+ System.out.println("utility access: " + utility_access + " ----- =" + betaWalkTT_h + " * " + accessTime_h);
+ System.out.println("utility drt (time): " + utilityDrtTime + " ----- =" + betaDrtTT_h + " * " + totalTime_h);
+ System.out.println("utility drt (distance): " + utilityDrtDistance + " ----- =" + betaDrtDist_m + " * " + directRideDistance_m);
+ System.out.println("utility drt (constant): " + utilityDrtConstant);
+ System.out.println("utility egress: " + Math.log(sumExpVjkWalk));
+// System.out.println("utility egress: (sumExpVjkWalk) exponential of utility, sum over all opportunities near stop: : " + sumExpVjkWalk);
+
expSum += Math.exp(this.scoringConfigGroup.getBrainExpBeta() *
- (walkUtilityMeasuringPoint2Road + modeSpecificConstant
- + congestedCarUtilityRoad2Node + utilityDrt))
+ (utility_access + utilityDrtTime + utilityDrtDistance + utilityDrtConstant ))
* sumExpVjkWalk;
}
return expSum;
@@ -185,9 +192,9 @@ public double computeContributionOfOpportunity(ActivityFacility origin,
public EstimatedDrtAccessibilityContributionCalculator duplicate() {
LOG.info("Creating another EstimatedDrtAccessibilityContributionCalculator object.");
EstimatedDrtAccessibilityContributionCalculator estimatedDrtAccessibilityContributionCalculator =
- new EstimatedDrtAccessibilityContributionCalculator(this.mode, this.travelTime, this.travelDisutilityFactory, this.scenario);
+ new EstimatedDrtAccessibilityContributionCalculator(this.mode, this.travelTime, this.travelDisutilityFactory, this.scenario, tripRouter);
estimatedDrtAccessibilityContributionCalculator.subNetwork = this.subNetwork;
- estimatedDrtAccessibilityContributionCalculator.aggregatedMeasurePoints = this.aggregatedMeasurePoints;
+// estimatedDrtAccessibilityContributionCalculator.aggregatedMeasurePoints = this.aggregatedMeasurePoints;
estimatedDrtAccessibilityContributionCalculator.aggregatedOpportunities = this.aggregatedOpportunities;
return estimatedDrtAccessibilityContributionCalculator;
}
@@ -203,4 +210,50 @@ public Map, ArrayList> getAggregat
public Map, AggregationObject> getAgregatedOpportunities() {
return aggregatedOpportunities;
}
+
+
+ public final Map, AggregationObject> aggregateOpportunitiesWithSameNearestDrtStop(
+ final ActivityFacilities opportunities, Network network, Config config ) {
+ // yyyy this method ignores the "capacities" of the facilities. kai, mar'14
+ // for now, we decided not to add "capacities" as it is not needed for current projects. dz, feb'16
+
+// double walkSpeed_m_h = config.routing().getTeleportedModeSpeeds().get(TransportMode.walk) * 3600.;
+ AccessibilityConfigGroup acg = ConfigUtils.addOrGetModule(config, AccessibilityConfigGroup.GROUP_NAME, AccessibilityConfigGroup.class);
+
+ LOG.info("Aggregating " + opportunities.getFacilities().size() + " opportunities with same nearest node...");
+ Map, AggregationObject> opportunityClusterMap = new ConcurrentHashMap<>();
+
+ for (ActivityFacility opportunity : opportunities.getFacilities().values()) {
+
+ Optional> facilities = stopFinder.findFacilities(opportunity, opportunity, null);
+ DrtStopFacility nearestStop = (DrtStopFacility) facilities.get().getKey();
+
+ List extends PlanElement> planElements = tripRouter.calcRoute(TransportMode.walk, nearestStop, opportunity, 10 * 3600., null, null);// departure time should matter for walk
+ double egressTime_s = ((Leg) planElements.get(0)).getTravelTime().seconds();
+
+ double VjkWalkTravelTime = egressTime_s / 3600 * betaWalkTT_h; // a.k.a utility_egress
+
+ double expVjk = Math.exp(config.scoring().getBrainExpBeta() * VjkWalkTravelTime);
+
+
+ // add Vjk to sum
+ AggregationObject jco = opportunityClusterMap.get(nearestStop.getId()); // Why "jco"?
+ if (jco == null) {
+ jco = new AggregationObject(opportunity.getId(), null, null, nearestStop, 0.);
+ opportunityClusterMap.put(nearestStop.getId(), jco);
+ }
+ if (acg.isUseOpportunityWeights()) {
+ if (opportunity.getAttributes().getAttribute( Labels.WEIGHT ) == null) {
+ throw new RuntimeException("If option \"useOpportunityWeights\" is used, the facilities must have an attribute with key " + Labels.WEIGHT + ".");
+ } else {
+ double weight = Double.parseDouble(opportunity.getAttributes().getAttribute( Labels.WEIGHT ).toString() );
+ jco.addObject(opportunity.getId(), expVjk * Math.pow(weight, acg.getWeightExponent()));
+ }
+ } else {
+ jco.addObject(opportunity.getId(), expVjk);
+ }
+ }
+ LOG.info("Aggregated " + opportunities.getFacilities().size() + " opportunities to " + opportunityClusterMap.size() + " nodes.");
+ return opportunityClusterMap;
+ }
}
diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/router/DvrpRoutingModule.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/router/DvrpRoutingModule.java
index 678039145d1..a3cf450ba34 100644
--- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/router/DvrpRoutingModule.java
+++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/router/DvrpRoutingModule.java
@@ -69,6 +69,10 @@ public DvrpRoutingModule(RoutingModule mainRouter, RoutingModule accessRouter, R
this.timeInterpretation = timeInterpretation;
}
+ public AccessEgressFacilityFinder getStopFinder() {
+ return stopFinder;
+ }
+
@Override
public List extends PlanElement> calcRoute(RoutingRequest request) {
final Facility fromFacility = request.getFromFacility();