Commit 742ff4b6 authored by Sebastian Hörl's avatar Sebastian Hörl
Browse files

Merge branch 'cost_calculator' into 'master'

Add cost calculator (prices not used yet)

See merge request !10
parents 5100985f 55a97116
...@@ -6,6 +6,8 @@ public class SharedAVConfigGroup extends ReflectiveConfigGroup { ...@@ -6,6 +6,8 @@ public class SharedAVConfigGroup extends ReflectiveConfigGroup {
public final static String GROUP_NAME = "shared_avs"; public final static String GROUP_NAME = "shared_avs";
private final static String USE_SHARED_AVS = "useSharedAVs"; private final static String USE_SHARED_AVS = "useSharedAVs";
private final static String USE_COST_CALCULATOR = "useCostCalculator";
private final static String TAXI_FLEET_SIZE = "taxiFleetSize"; private final static String TAXI_FLEET_SIZE = "taxiFleetSize";
private final static String POOLED_FLEET_SIZE = "pooledFleetSize"; private final static String POOLED_FLEET_SIZE = "pooledFleetSize";
...@@ -16,7 +18,10 @@ public class SharedAVConfigGroup extends ReflectiveConfigGroup { ...@@ -16,7 +18,10 @@ public class SharedAVConfigGroup extends ReflectiveConfigGroup {
private final static String WAITING_TIME_ZONE_SHAPEFILE = "waitingTimeZoneShapefile"; private final static String WAITING_TIME_ZONE_SHAPEFILE = "waitingTimeZoneShapefile";
private final static String WAITING_TIME_ZONE_ATTRIBUTE = "waitingTimeZoneAttribute"; private final static String WAITING_TIME_ZONE_ATTRIBUTE = "waitingTimeZoneAttribute";
private final static String COST_CALCULATOR_SCALING_FACTOR = "costCalculatorScalingFactor";
private boolean useSharedAVs = false; private boolean useSharedAVs = false;
private boolean useCostCalculator = false;
private int taxiFleetSize = 100; private int taxiFleetSize = 100;
private int pooledFleetSize = 0; private int pooledFleetSize = 0;
...@@ -28,6 +33,8 @@ public class SharedAVConfigGroup extends ReflectiveConfigGroup { ...@@ -28,6 +33,8 @@ public class SharedAVConfigGroup extends ReflectiveConfigGroup {
private String waitingTimeZoneAttribute = "WZONE"; private String waitingTimeZoneAttribute = "WZONE";
private String waitingTimeZoneShapefile = "waiting_time_zones.shp"; private String waitingTimeZoneShapefile = "waiting_time_zones.shp";
private double costCalculatorScalingFactor = 1.0;
public SharedAVConfigGroup() { public SharedAVConfigGroup() {
super(GROUP_NAME); super(GROUP_NAME);
} }
...@@ -42,6 +49,16 @@ public class SharedAVConfigGroup extends ReflectiveConfigGroup { ...@@ -42,6 +49,16 @@ public class SharedAVConfigGroup extends ReflectiveConfigGroup {
this.useSharedAVs = useSharedAVs; this.useSharedAVs = useSharedAVs;
} }
@StringGetter(USE_COST_CALCULATOR)
public boolean getUseCostCalculator() {
return useCostCalculator;
}
@StringSetter(USE_COST_CALCULATOR)
public void setUseCostCalculator(boolean useCostCalculator) {
this.useCostCalculator = useCostCalculator;
}
@StringGetter(TAXI_FLEET_SIZE) @StringGetter(TAXI_FLEET_SIZE)
public int getTaxiFleetSize() { public int getTaxiFleetSize() {
return taxiFleetSize; return taxiFleetSize;
...@@ -111,4 +128,14 @@ public class SharedAVConfigGroup extends ReflectiveConfigGroup { ...@@ -111,4 +128,14 @@ public class SharedAVConfigGroup extends ReflectiveConfigGroup {
public void setWaitingTimeZoneAttribute(String waitingTimeZoneAttribute) { public void setWaitingTimeZoneAttribute(String waitingTimeZoneAttribute) {
this.waitingTimeZoneAttribute = waitingTimeZoneAttribute; this.waitingTimeZoneAttribute = waitingTimeZoneAttribute;
} }
@StringGetter(COST_CALCULATOR_SCALING_FACTOR)
public double getCostCalculatorScalingFactor() {
return costCalculatorScalingFactor;
}
@StringSetter(COST_CALCULATOR_SCALING_FACTOR)
public void setCostCalculatorScalingFactor(double costCalculatorScalingFactor) {
this.costCalculatorScalingFactor = costCalculatorScalingFactor;
}
} }
...@@ -14,6 +14,7 @@ import ch.ethz.matsim.av.framework.AVConfigGroup; ...@@ -14,6 +14,7 @@ import ch.ethz.matsim.av.framework.AVConfigGroup;
import ch.ethz.matsim.av.framework.AVModule; import ch.ethz.matsim.av.framework.AVModule;
import ch.ethz.matsim.discrete_mode_choice.modules.config.DiscreteModeChoiceConfigGroup; import ch.ethz.matsim.discrete_mode_choice.modules.config.DiscreteModeChoiceConfigGroup;
import ch.ethz.matsim.projects.astra_2018_002.ASTRAQSimModule; import ch.ethz.matsim.projects.astra_2018_002.ASTRAQSimModule;
import ch.ethz.matsim.projects.astra_2018_002.shared_av.pricing.AVPricingModule;
public class SharedAVConfigurator { public class SharedAVConfigurator {
static public void configure(Config config) { static public void configure(Config config) {
...@@ -74,6 +75,11 @@ public class SharedAVConfigurator { ...@@ -74,6 +75,11 @@ public class SharedAVConfigurator {
controller.addOverridingModule(new AVModule()); controller.addOverridingModule(new AVModule());
controller.addOverridingModule(new SharedAVModule()); controller.addOverridingModule(new SharedAVModule());
controller.addOverridingModule(new ASTRAQSimModule()); controller.addOverridingModule(new ASTRAQSimModule());
if (sharedConfig.getUseCostCalculator()) {
double scalingFactor = sharedConfig.getCostCalculatorScalingFactor();
controller.addOverridingModule(new AVPricingModule(scalingFactor, 10));
}
} }
} }
} }
...@@ -47,6 +47,9 @@ public class SharedAVModule extends AbstractDiscreteModeChoiceExtension { ...@@ -47,6 +47,9 @@ public class SharedAVModule extends AbstractDiscreteModeChoiceExtension {
public static final String WAITING_TIME_GROUP_ATTRIBUTE = "waitingTimeGroup"; public static final String WAITING_TIME_GROUP_ATTRIBUTE = "waitingTimeGroup";
public static final long POOLED_NUMBER_OF_SEATS = 4;
public static final String POOLED_COST_TYPE = "Midsize";
@Override @Override
protected void installExtension() { protected void installExtension() {
bindTripConstraintFactory(CONSTRAINT_NAME).to(ServiceAreaConstraint.Factory.class); bindTripConstraintFactory(CONSTRAINT_NAME).to(ServiceAreaConstraint.Factory.class);
......
package ch.ethz.matsim.projects.astra_2018_002.shared_av.pricing;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.matsim.core.controler.OutputDirectoryHierarchy;
import org.matsim.core.controler.events.IterationEndsEvent;
import org.matsim.core.controler.listener.IterationEndsListener;
import ch.ethz.matsim.av_cost_calculator.CostCalculatorExecutor;
import ch.ethz.matsim.av_cost_calculator.run.ParameterBuilder;
import ch.ethz.matsim.av_cost_calculator.run.PricingAnalysisHandler;
public class AVPricingListener implements IterationEndsListener {
private final PricingAnalysisHandler handler;
private final CostCalculatorExecutor executor;
private final double scenarioScale;
private final int horizon;
private List<Double> history = new LinkedList<>();
private final BufferedWriter writer;
private double activePrice = 0.0;
private final String vehicleType;
public AVPricingListener(String operator, String vehicleType, double scenarioScale, int horizon,
PricingAnalysisHandler handler, CostCalculatorExecutor executor, OutputDirectoryHierarchy output)
throws IOException {
this.scenarioScale = scenarioScale;
this.horizon = horizon;
this.handler = handler;
this.executor = executor;
this.vehicleType = vehicleType;
writer = new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(output.getOutputFilename("prices_" + operator + ".csv"))));
writer.write("iteration;active_price;computed_price\n");
writer.flush();
for (int i = 0; i < horizon; i++) {
history.add(0.0);
}
}
@Override
public void notifyIterationEnds(IterationEndsEvent event) {
double totalTime = 24.0 * 3600.0;
Map<String, String> parameters = new ParameterBuilder(scenarioScale, totalTime, vehicleType).build(handler);
double price = executor.computePricePerPassengerKm(parameters);
handler.resetHandler();
if (!Double.isNaN(price)) {
history.remove(0);
history.add(price);
}
activePrice = history.stream().mapToDouble(d -> d).sum() / (double) horizon;
try {
writer.write(String.format("%d;%f;%f\n", event.getIteration(), activePrice, price));
writer.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public double getPricePerKm() {
return activePrice;
}
}
package ch.ethz.matsim.projects.astra_2018_002.shared_av.pricing;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import org.matsim.api.core.v01.network.Network;
import org.matsim.core.controler.AbstractModule;
import org.matsim.core.controler.OutputDirectoryHierarchy;
import com.google.inject.Key;
import com.google.inject.Provides;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
import com.google.inject.name.Names;
import ch.ethz.matsim.av.framework.AVModule;
import ch.ethz.matsim.av_cost_calculator.CostCalculator;
import ch.ethz.matsim.av_cost_calculator.CostCalculatorExecutor;
import ch.ethz.matsim.av_cost_calculator.run.AVValidator;
import ch.ethz.matsim.av_cost_calculator.run.IdAVValidator;
import ch.ethz.matsim.av_cost_calculator.run.MultiOccupancyAnalysisHandler;
import ch.ethz.matsim.av_cost_calculator.run.PricingAnalysisHandler;
import ch.ethz.matsim.av_cost_calculator.run.SingleOccupancyAnalysisHandler;
import ch.ethz.matsim.projects.astra_2018_002.shared_av.SharedAVModule;
public class AVPricingModule extends AbstractModule {
private final double scenarioScale;
private final int horizon;
public AVPricingModule(double scenarioScale, int horizon) {
this.scenarioScale = scenarioScale;
this.horizon = horizon;
}
@Override
public void install() {
addEventHandlerBinding().to(Key.get(PricingAnalysisHandler.class, Names.named(SharedAVModule.AV_TAXI)));
addControlerListenerBinding().to(Key.get(AVPricingListener.class, Names.named(SharedAVModule.AV_TAXI)));
addEventHandlerBinding().to(Key.get(PricingAnalysisHandler.class, Names.named(SharedAVModule.AV_POOL)));
addControlerListenerBinding().to(Key.get(AVPricingListener.class, Names.named(SharedAVModule.AV_POOL)));
}
@Provides
@Singleton
@Named(SharedAVModule.AV_TAXI)
public AVPricingListener provideTaxiPricingListener(@Named(SharedAVModule.AV_TAXI) PricingAnalysisHandler handler,
CostCalculatorExecutor executor, OutputDirectoryHierarchy output) throws IOException {
return new AVPricingListener(SharedAVModule.AV_TAXI, "Solo", scenarioScale, horizon, handler, executor, output);
}
@Provides
@Singleton
@Named(SharedAVModule.AV_POOL)
public AVPricingListener providePoolPricingListener(@Named(SharedAVModule.AV_POOL) PricingAnalysisHandler handler,
CostCalculatorExecutor executor, OutputDirectoryHierarchy output) throws IOException {
return new AVPricingListener(SharedAVModule.AV_POOL, SharedAVModule.POOLED_COST_TYPE, scenarioScale, horizon,
handler, executor, output);
}
@Provides
@Singleton
@Named(SharedAVModule.AV_TAXI)
public PricingAnalysisHandler provideTaxiPricingAnalysisHandler(@Named(AVModule.AV_MODE) Network network) {
double totalTime = 24.0 * 3600.0;
AVValidator validator = new IdAVValidator(SharedAVModule.AV_TAXI);
return new SingleOccupancyAnalysisHandler(network, validator, totalTime);
}
@Provides
@Singleton
@Named(SharedAVModule.AV_POOL)
public PricingAnalysisHandler providePooledPricingAnalysisHandler(@Named(AVModule.AV_MODE) Network network) {
double totalTime = 24.0 * 3600.0;
AVValidator validator = new IdAVValidator(SharedAVModule.AV_POOL);
return new MultiOccupancyAnalysisHandler(network, validator, totalTime, SharedAVModule.POOLED_NUMBER_OF_SEATS);
}
@Provides
@Singleton
public CostCalculatorExecutor provideCostCalculatorExecutor(OutputDirectoryHierarchy outputHierarchy) {
URL sourceURL = CostCalculator.class.getClassLoader().getResource("ch/ethz/matsim/av_cost_calculator/");
File workingDirectory = new File(outputHierarchy.getTempPath() + "/av_cost_calculator");
workingDirectory.mkdirs();
return new CostCalculatorExecutor(workingDirectory, sourceURL);
}
}
...@@ -14,6 +14,7 @@ import ch.ethz.matsim.av.config.AVGeneratorConfig; ...@@ -14,6 +14,7 @@ import ch.ethz.matsim.av.config.AVGeneratorConfig;
import ch.ethz.matsim.av.data.AVVehicle; import ch.ethz.matsim.av.data.AVVehicle;
import ch.ethz.matsim.av.generator.AVGenerator; import ch.ethz.matsim.av.generator.AVGenerator;
import ch.ethz.matsim.projects.astra_2018_002.shared_av.SharedAVConfigGroup; import ch.ethz.matsim.projects.astra_2018_002.shared_av.SharedAVConfigGroup;
import ch.ethz.matsim.projects.astra_2018_002.shared_av.SharedAVModule;
public class ServiceAreaGenerator implements AVGenerator { public class ServiceAreaGenerator implements AVGenerator {
private final String prefix; private final String prefix;
...@@ -44,7 +45,8 @@ public class ServiceAreaGenerator implements AVGenerator { ...@@ -44,7 +45,8 @@ public class ServiceAreaGenerator implements AVGenerator {
Id<Vehicle> vehicleId = Id.create(prefix + "_" + String.valueOf(numberOfGeneratedVehicles), Vehicle.class); Id<Vehicle> vehicleId = Id.create(prefix + "_" + String.valueOf(numberOfGeneratedVehicles), Vehicle.class);
Link startLink = links.get(random.nextInt(links.size())); Link startLink = links.get(random.nextInt(links.size()));
return new AVVehicle(vehicleId, startLink, 4.0, 0.0, Double.POSITIVE_INFINITY); return new AVVehicle(vehicleId, startLink, (double) SharedAVModule.POOLED_NUMBER_OF_SEATS, 0.0,
Double.POSITIVE_INFINITY);
} }
public static class Factory implements AVGeneratorFactory { public static class Factory implements AVGeneratorFactory {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment