Skip to content

Commit

Permalink
Destination intervention update, new mode choice models
Browse files Browse the repository at this point in the history
  • Loading branch information
CorinStaves committed Oct 22, 2024
1 parent dcc6507 commit 88d76da
Show file tree
Hide file tree
Showing 6 changed files with 320 additions and 22 deletions.
45 changes: 31 additions & 14 deletions src/main/java/accessibility/RunIntervention.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import accessibility.decay.*;
import accessibility.resources.AccessibilityProperties;
import accessibility.resources.AccessibilityResources;
import com.google.common.math.LongMath;
import gis.GisUtils;
import gis.GpkgReader;
import io.ioUtils;
Expand Down Expand Up @@ -207,40 +208,52 @@ private static void runIntervention(String propertiesFilepath) throws IOExceptio

// Write new node locations
log.info("Writing new node locations...");
printNewDestinations(destinationsOutputFile, network, candidateNodeIdMap, demand, newDestinations, newDestinationWeight, destinationDescriptions);
printNewDestinations(destinationsOutputFile, network, candidateNodeIdMap, population, supply, demand, newDestinations, newDestinationWeight, destinationDescriptions);

// Write changes in population accessibility
if(demandOutputFile != null) {
log.info("Writing demand-side output for each (potential) destination node...");
writeEachIteration(demandOutputFile, network, candidateNodeIdMap, demand, destinationDescriptions);
writeEachIteration(demandOutputFile, network, candidateNodeIdMap, demand, destinationDescriptions,false);
}

if(supplyOutputFile != null) {
log.info("Writing supply-side output for each population location and iteration...");
writeEachIteration(supplyOutputFile, network, populationNodeIdMap, supply, destinationDescriptions);
writeEachIteration(supplyOutputFile, network, populationNodeIdMap, supply, destinationDescriptions,true);
}
}


// Prints new destinations and details
private static void printNewDestinations(String outputFile, Network network, IdMap<Node,String> nodes,
List<Map<Id<Node>,double[]>> demand, List<List<Id<Node>>> newNodes,
double[] newWeights,
private static void printNewDestinations(String outputFile, Network network, IdMap<Node,String> nodes, IdMap<Node,Double> population,
List<Map<Id<Node>, double[]>> supply, List<Map<Id<Node>,double[]>> demand,
List<List<Id<Node>>> newNodes, double[] newWeights,
List<String> destinationDescriptions) {
PrintWriter out = ioUtils.openFileForSequentialWriting(new File(outputFile),false);
assert out != null;

// Write header
out.println("type" + SEP + "n" + SEP + "id" + SEP + "nodeId" + SEP + "x" + SEP + "y" + SEP + "weight" + SEP + "demand");
out.println("type" + SEP + "n" + SEP + "id" + SEP + "nodeId" + SEP + "x" + SEP + "y" + SEP + "weight" + SEP + "demand" + SEP + "supply" + SEP + "supplyRatio");

// Write rows
int i = 0;
for(List<Id<Node>> iteration : newNodes) {
int j = 0;
for(Id<Node> nodeId : iteration) {
Coord coord = network.getNodes().get(nodeId).getCoord();
String line = destinationDescriptions.get(j) + SEP + i + SEP + nodes.get(nodeId) + SEP + nodeId.toString() + SEP +
coord.getX() + SEP + coord.getY() + SEP + newWeights[j] + SEP + demand.get(i).get(nodeId)[j];
for(Id<Node> destNodeId : iteration) {
Coord coord = network.getNodes().get(destNodeId).getCoord();
double supplyRatio = 0;
double supplyTotal = 0;
for(Map.Entry<Id<Node>,Double> e : population.entrySet()) {
Id<Node> popNodeId = e.getKey();
double pop = e.getValue();
double supplyAtNode = supply.get(i+1).get(popNodeId)[j];
if(supplyAtNode > 0) {
supplyTotal += pop * supplyAtNode;
supplyRatio += pop * (1 - supply.get(0).get(popNodeId)[j] / supplyAtNode);
}
}
String line = destinationDescriptions.get(j) + SEP + i + SEP + nodes.get(destNodeId) + SEP + destNodeId.toString() + SEP +
coord.getX() + SEP + coord.getY() + SEP + newWeights[j] + SEP + demand.get(i).get(destNodeId)[j] + SEP +
supplyTotal + SEP + supplyRatio;
out.println(line);
j++;
}
Expand All @@ -250,7 +263,7 @@ private static void printNewDestinations(String outputFile, Network network, IdM
}

private static void writeEachIteration(String outputFile, Network network, IdMap<Node,String> nodes, List<Map<Id<Node>,double[]>> results,
List<String> destinationDescriptions) {
List<String> destinationDescriptions, boolean sparse) {
PrintWriter out = ioUtils.openFileForSequentialWriting(new File(outputFile),false);
assert out != null;

Expand All @@ -260,7 +273,9 @@ private static void writeEachIteration(String outputFile, Network network, IdMap
StringBuilder builder = new StringBuilder();
builder.append("id").append(SEP).append("node").append(SEP).append("x").append(SEP).append("y").append(SEP).append("type");
for(int i = 0 ; i < iterations ; i++) {
builder.append(SEP).append("it_").append(i);
if(i == 0 || LongMath.isPowerOfTwo(i) || !sparse) {
builder.append(SEP).append("it_").append(i);
}
}
out.println(builder);

Expand All @@ -271,7 +286,9 @@ private static void writeEachIteration(String outputFile, Network network, IdMap
builder = new StringBuilder();
builder.append(e.getValue()).append(SEP).append(e.getKey()).append(SEP).append(coord.getX()).append(SEP).append(coord.getY()).append(SEP).append(destinationDescriptions.get(j));
for (int i = 0; i < iterations; i++) {
builder.append(SEP).append(results.get(i).get(e.getKey())[j]);
if(i == 0 || LongMath.isPowerOfTwo(i) || !sparse) {
builder.append(SEP).append(results.get(i).get(e.getKey())[j]);
}
}
out.println(builder);
}
Expand Down
12 changes: 8 additions & 4 deletions src/main/java/estimation/RunMnlManchester.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package estimation;

import estimation.specifications.AbstractModelSpecification;
import estimation.specifications.manchester.HBA;
import estimation.specifications.manchester.HBD;
import estimation.specifications.manchester.NHBO;
import estimation.specifications.manchester.NHBW;
import gis.GisUtils;
import gis.GpkgReader;
import io.DiaryReader;
Expand All @@ -18,6 +21,7 @@
import routing.Bicycle;
import routing.travelTime.WalkTravelTime;
import smile.classification.ClassLabels;
import trip.Place;
import trip.Trip;

import java.io.IOException;
Expand Down Expand Up @@ -89,13 +93,13 @@ public static void main(String[] args) throws IOException, FactoryException {
TravelTime ttWalk = new WalkTravelTime();
TravelTime ttBike = bicycle.getTravelTimeFast(networkBike);

// Deal with intrazonal trips – can remove after we get X/Y coordinates for TRADS)
Set<SimpleFeature> OAs = GisUtils.readGpkg("zones/2011/gm_oa.gpkg");
// Deal with intrazonal trips – can remove after we get X/Y coordinates for TRADS
Set<SimpleFeature> OAs = GisUtils.readGpkg("zones/2011/gm_oa_buf.gpkg");

// Initialise utility specification
u = new HBD(logitData,trip_data,OAs,networkBike,bike,ttBike,networkWalk,null,ttWalk);
u = new NHBO(logitData,trip_data,OAs,networkBike,bike,ttBike,networkWalk,null,ttWalk);
} else {
u = new HBD(logitData,null,null,null,null,null,null,null,null);
u = new NHBO(logitData,null,null,null,null,null,null,null,null);
}

// Start model
Expand Down
13 changes: 9 additions & 4 deletions src/main/java/estimation/dynamic/RouteDataDynamic.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

public class RouteDataDynamic implements RouteData, DynamicComponent {

private final static boolean ENABLE_DYNAMIC_ROUTING = false;
private final static boolean ENABLE_DYNAMIC_ROUTING = true;
private final static Logger logger = Logger.getLogger(RouteDataDynamic.class);
private final int numberOfThreads;
final int tripCount;
Expand Down Expand Up @@ -215,7 +215,7 @@ public double getAttribute(int i, int j) {
}

public void update(double[] xVarOnly) {
if(ENABLE_DYNAMIC_ROUTING) {
if(ENABLE_DYNAMIC_ROUTING && !attributes.isEmpty()) {
updatePathData(xVarOnly);
computeRouteStats();
}
Expand Down Expand Up @@ -392,7 +392,7 @@ private static void computeIntrazonalTripData(PathData pathData, Trip[] trips, A

// Determine set of links for each zone
Map<SimpleFeature, IdSet<Link>> linksPerFeature = GisUtils.calculateLinksIntersectingZones(zones,net);
Map<String,IdSet<Link>> linksPerZone = linksPerFeature.entrySet().stream().collect(Collectors.toMap(e -> ((String) e.getKey().getAttribute("geo_code")), Map.Entry::getValue));
Map<String,IdSet<Link>> linksPerZone = linksPerFeature.entrySet().stream().collect(Collectors.toMap(e -> ((String) e.getKey().getAttribute("OA11CD")), Map.Entry::getValue));

// Identify intrazonal trips
int intrazonalTripCount = 0;
Expand All @@ -410,7 +410,12 @@ private static void computeIntrazonalTripData(PathData pathData, Trip[] trips, A
}
double totLength = 0;
double[] totAttributes = new double[attributes.size()];
for(Id<Link> linkId : linksPerZone.get(trips[i].getZone(Place.ORIGIN))) {
IdSet<Link> linkIds = linksPerZone.get(trips[i].getZone(ORIGIN));
if(linkIds == null) {
throw new RuntimeException("No zone data for intrazonal trip, household " + trips[i].getHouseholdId() +
" person " + trips[i].getPersonId() + " trip " + trips[i].getTripId());
}
for(Id<Link> linkId : linkIds) {
Link link = net.getLinks().get(linkId);
double linkLength = link.getLength();
totLength += linkLength;
Expand Down
89 changes: 89 additions & 0 deletions src/main/java/estimation/specifications/manchester/HBA.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package estimation.specifications.manchester;

import estimation.LogitData;
import estimation.RouteAttribute;
import org.matsim.api.core.v01.TransportMode;
import org.matsim.api.core.v01.network.Network;
import org.matsim.core.router.util.TravelTime;
import org.matsim.vehicles.Vehicle;
import org.opengis.feature.simple.SimpleFeature;
import routing.Gradient;
import routing.disutility.components.JctStress;
import routing.disutility.components.LinkAmbience;
import routing.disutility.components.LinkStress;
import trip.Trip;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class HBA extends MNL_Manchester {

private final static List<String> SOCIODEMOGRAPHIC_VARIABLES = List.of(
"p.age_group_agg_5_24","p.age_group_agg_40_69","p.age_group_agg_70",
"p.female",
"p.occupation_worker",
"hh.cars_gr_0","hh.cars_gr_2","hh.cars_gr_3");

public HBA(LogitData data, Trip[] trips, Set<SimpleFeature> OAs,
Network netBike, Vehicle vehBike, TravelTime ttBike,
Network netWalk, Vehicle vehWalk, TravelTime ttWalk) {
super(data,trips,OAs,netBike,vehBike,ttBike,netWalk,vehWalk,ttWalk);
}

@Override
List<String> sociodemographicVariables() {
return SOCIODEMOGRAPHIC_VARIABLES;
}

List<RouteAttribute> streetEnvironmentAttributesBike() {
List<RouteAttribute> bike = new ArrayList<>();
// bike.add(new RouteAttribute("g_bike_grad", l -> Math.max(Math.min(Gradient.getGradient(l),0.5),0.)));
// bike.add(new RouteAttribute("g_bike_vgvi", l -> Math.max(0.,0.81 - LinkAmbience.getVgviFactor(l))));
// bike.add(new RouteAttribute("g_bike_stressLink", l -> LinkStress.getStress(l, TransportMode.bike)));
return bike;
}

List<RouteAttribute> streetEnvironmentAttributesWalk() {
List<RouteAttribute> walk = new ArrayList<>();
walk.add(new RouteAttribute("g_walk_vgvi", l -> Math.max(0.,0.81 - LinkAmbience.getVgviFactor(l))));
// walk.add(new RouteAttribute("g_walk_stressJct", l -> JctStress.getStressProp(l,TransportMode.walk)));
// walk.add(new RouteAttribute("g_walk_speed", l -> Math.min(1.,l.getFreespeed() / 22.35)));
// walk.add(new RouteAttribute("g_walk_aadt", l -> Math.min(1.,((int) l.getAttributes().getAttribute("aadt")) * 0.865/6000.)));
return walk;
}

@Override
protected List<String> fixed() {
List<String> fixed = coefficients().keySet().stream().filter(s -> (s.contains("carD"))).collect(Collectors.toList());
fixed.add("b_pt_hh.cars_gr_2");
fixed.add("b_pt_hh.cars_gr_3");
fixed.add("b_bike_hh.cars_gr_0");
fixed.add("b_bike_hh.cars_gr_2");
fixed.add("b_bike_hh.cars_gr_3");
fixed.add("b_bike_p.female");
fixed.add("b_walk_hh.cars_gr_2");
fixed.add("b_pt_p.age_group_agg_5_24");
fixed.add("b_pt_p.age_group_agg_40_69");
fixed.add("b_pt_p.age_group_agg_70");
fixed.add("b_bike_p.age_group_agg_5_24");
fixed.add("b_bike_p.age_group_agg_40_69");
fixed.add("b_bike_p.age_group_agg_70");
fixed.add("b_bike_p.occupation_worker");
// fixed.add("b_carP_p.age_group_agg_5_14");
// fixed.add("b_carP_hh.income_agg_high");
// fixed.add("b_carP_t.full_purpose_HBO");
// fixed.add("b_bike_p.age_group_agg_40_69");
// fixed.add("b_bike_hh.income_agg_high");
// fixed.add("g_bike_vgvi");
// fixed.add("g_bike_stressJct");
// fixed.add("g_bike_stressJct_f");
// fixed.add("g_bike_stressJct_c");
// fixed.add("g_walk_grad");
// fixed.add("g_walk_stressLink");
// fixed.add("g_walk_stressLink_f");
// fixed.add("g_walk_stressJct_f");
return fixed;
}
}
94 changes: 94 additions & 0 deletions src/main/java/estimation/specifications/manchester/NHBO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package estimation.specifications.manchester;

import estimation.LogitData;
import estimation.RouteAttribute;
import org.matsim.api.core.v01.TransportMode;
import org.matsim.api.core.v01.network.Network;
import org.matsim.core.router.util.TravelTime;
import org.matsim.vehicles.Vehicle;
import org.opengis.feature.simple.SimpleFeature;
import routing.Gradient;
import routing.disutility.components.JctStress;
import routing.disutility.components.LinkAmbience;
import routing.disutility.components.LinkStress;
import trip.Trip;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class NHBO extends MNL_Manchester {

private final static List<String> SOCIODEMOGRAPHIC_VARIABLES = List.of(
"p.age_group_agg_5_14","p.age_group_agg_15_24","p.age_group_agg_40_69","p.age_group_agg_70",
"p.female",
"p.occupation_worker",
"hh.cars_gr_0","hh.cars_gr_23");

public NHBO(LogitData data, Trip[] trips, Set<SimpleFeature> OAs,
Network netBike, Vehicle vehBike, TravelTime ttBike,
Network netWalk, Vehicle vehWalk, TravelTime ttWalk) {
super(data,trips,OAs,netBike,vehBike,ttBike,netWalk,vehWalk,ttWalk);
}

@Override
List<String> sociodemographicVariables() {
return SOCIODEMOGRAPHIC_VARIABLES;
}

List<RouteAttribute> streetEnvironmentAttributesBike() {
List<RouteAttribute> bike = new ArrayList<>();
// bike.add(new RouteAttribute("g_bike_grad", l -> Math.max(Math.min(Gradient.getGradient(l),0.5),0.)));
// bike.add(new RouteAttribute("g_bike_vgvi", l -> Math.max(0.,0.81 - LinkAmbience.getVgviFactor(l))));
// bike.add(new RouteAttribute("g_bike_stressLink", l -> LinkStress.getStress(l, TransportMode.bike)));
return bike;
}

List<RouteAttribute> streetEnvironmentAttributesWalk() {
List<RouteAttribute> walk = new ArrayList<>();
// walk.add(new RouteAttribute("g_walk_vgvi", l -> Math.max(0.,0.81 - LinkAmbience.getVgviFactor(l))));
// walk.add(new RouteAttribute("g_walk_stressJct", l -> JctStress.getStressProp(l,TransportMode.walk)));
walk.add(new RouteAttribute("g_walk_speed", l -> Math.min(1.,l.getFreespeed() / 22.35)));
// walk.add(new RouteAttribute("g_walk_aadt", l -> Math.min(1.,((int) l.getAttributes().getAttribute("aadt")) * 0.865/6000.)));
// walk.add(new RouteAttribute("g_walk_speed_aadt", l -> Math.min(1.,l.getFreespeed() / 22.35) * Math.min(1.,((int) l.getAttributes().getAttribute("aadt")) * 0.865/6000.)));
return walk;
}

@Override
protected List<String> fixed() {
List<String> fixed = coefficients().keySet().stream().filter(s -> (s.contains("carD"))).collect(Collectors.toList());
fixed.add("b_carP_p.age_group_agg_5_14");
fixed.add("b_carP_hh.cars_gr_0");
fixed.add("b_bike_p.age_group_agg_5_14");
fixed.add("b_bike_p.age_group_agg_15_24");
fixed.add("b_bike_p.age_group_agg_40_69");
fixed.add("b_bike_p.age_group_agg_70");
fixed.add("b_pt_p.age_group_agg_40_69");
fixed.add("b_pt_p.age_group_agg_70");
// fixed.add("b_pt_p.occupation_worker");
fixed.add("b_bike_hh.cars_gr_0");
fixed.add("b_bike_hh.cars_gr_23");
fixed.add("b_bike_p.female");
fixed.add("b_bike_p.occupation_worker");
fixed.add("b_carP_hh.cars_gr_23");
fixed.add("b_walk_hh.cars_gr_23");
fixed.add("b_carP_p.age_group_agg_40_69");
fixed.add("b_carP_p.age_group_agg_70");
// fixed.add("b_carP_t.full_purpose_HBO");
// fixed.add("b_pt_hh.income_agg_high");
fixed.add("b_walk_p.occupation_worker");
fixed.add("b_walk_p.female");
fixed.add("b_pt_p.female");

// fixed.add("g_bike_vgvi");
// fixed.add("g_bike_stressJct");
// fixed.add("g_bike_stressJct_f");
// fixed.add("g_bike_stressJct_c");
// fixed.add("g_walk_grad");
// fixed.add("g_walk_stressLink");
// fixed.add("g_walk_stressLink_f");
// fixed.add("g_walk_stressJct_f");
return fixed;
}
}
Loading

0 comments on commit 88d76da

Please sign in to comment.