Skip to content

Commit

Permalink
Update carriers analysis (#3120)
Browse files Browse the repository at this point in the history
* renaming of method

* include also travelTime in analysis.
Report also in hours and kilometers.

* update test input
  • Loading branch information
kt86 authored Feb 20, 2024
1 parent 91288bf commit cf76818
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
import org.matsim.api.core.v01.Scenario;
import org.matsim.api.core.v01.events.Event;
import org.matsim.api.core.v01.events.LinkEnterEvent;
import org.matsim.api.core.v01.events.LinkLeaveEvent;
import org.matsim.api.core.v01.events.VehicleEntersTrafficEvent;
import org.matsim.api.core.v01.events.VehicleLeavesTrafficEvent;
import org.matsim.freight.carriers.Carrier;
import org.matsim.freight.carriers.CarriersUtils;
import org.matsim.freight.carriers.Tour;
Expand Down Expand Up @@ -55,15 +58,21 @@ public class FreightTimeAndDistanceAnalysisEventsHandler implements BasicEventHa
private final Map<Id<Vehicle>, Double> vehicleId2TourDuration = new LinkedHashMap<>();
private final Map<Id<Vehicle>, Double> vehicleId2TourLength = new LinkedHashMap<>();

private final Map<Id<Vehicle>, Double> vehicleId2TravelTime = new LinkedHashMap<>();

private final Map<Id<Vehicle>, Id<Carrier>> vehicleId2CarrierId = new LinkedHashMap<>();
private final Map<Id<Vehicle>, Id<Tour>> vehicleId2TourId = new LinkedHashMap<>();

private final Map<Id<VehicleType>, Double> vehicleTypeId2SumOfDuration = new LinkedHashMap<>();
private final Map<Id<VehicleType>, Double> vehicleTypeId2SumOfTourDuration = new LinkedHashMap<>();
private final Map<Id<VehicleType>, Double> vehicleTypeId2Mileage = new LinkedHashMap<>();
private final Map<Id<VehicleType>, Double> vehicleTypeId2TravelTime = new LinkedHashMap<>();

private final Map<Id<Vehicle>, VehicleType> vehicleId2VehicleType = new TreeMap<>();

private final Map<String, Double> tourStartTime = new LinkedHashMap<>();

private final Map<Id<Vehicle>, Double> vehicleEnteredLinkTime = new LinkedHashMap<>();


public FreightTimeAndDistanceAnalysisEventsHandler(Scenario scenario) {
this.scenario = scenario;
Expand All @@ -81,7 +90,7 @@ private void handleEvent(CarrierTourEndEvent event) {
double tourDuration = event.getTime() - tourStartTime.get(key);
vehicleId2TourDuration.put(event.getVehicleId(), tourDuration);
VehicleType vehType = VehicleUtils.findVehicle(event.getVehicleId(), scenario).getType();
vehicleTypeId2SumOfDuration.merge(vehType.getId(), tourDuration, Double::sum);
vehicleTypeId2SumOfTourDuration.merge(vehType.getId(), tourDuration, Double::sum);

//Some general information for this vehicle
vehicleId2CarrierId.putIfAbsent(event.getVehicleId(), event.getCarrierId());
Expand All @@ -93,38 +102,81 @@ private void handleEvent(CarrierTourEndEvent event) {
private void handleEvent(LinkEnterEvent event) {
final double distance = scenario.getNetwork().getLinks().get(event.getLinkId()).getLength();
vehicleId2TourLength.merge(event.getVehicleId(), distance, Double::sum);
vehicleEnteredLinkTime.put(event.getVehicleId(), event.getTime()); //Safe time when entering the link.

final Id<VehicleType> vehTypeId = VehicleUtils.findVehicle(event.getVehicleId(), scenario).getType().getId();
vehicleTypeId2Mileage.merge(vehTypeId, distance, Double::sum);
}

@Override public void handleEvent(Event event) {
//If the vehicle leaves a link at the end, the travelTime is calculated and stored.
private void handleEvent(LinkLeaveEvent event){
final Id<Vehicle> vehicleId = event.getVehicleId();
if (vehicleEnteredLinkTime.containsKey(vehicleId)){
double tt = event.getTime() - vehicleEnteredLinkTime.get(vehicleId);
vehicleId2TravelTime.merge(vehicleId, tt, Double::sum); //per vehicle

final Id<VehicleType> vehTypeId = VehicleUtils.findVehicle(event.getVehicleId(), scenario).getType().getId();
vehicleTypeId2TravelTime.merge(vehTypeId, tt, Double::sum); // per VehType

vehicleEnteredLinkTime.remove(vehicleId); //remove from that list.
}
}

//If the vehicle leaves a link because it reached its destination, the travelTime is calculated and stored.
private void handleEvent(VehicleLeavesTrafficEvent event){
final Id<Vehicle> vehicleId = event.getVehicleId();
if (vehicleEnteredLinkTime.containsKey(vehicleId)){
double tt = event.getTime() - vehicleEnteredLinkTime.get(vehicleId);
vehicleId2TravelTime.merge(vehicleId, tt, Double::sum);//per vehicle

final Id<VehicleType> vehTypeId = VehicleUtils.findVehicle(event.getVehicleId(), scenario).getType().getId();
vehicleTypeId2TravelTime.merge(vehTypeId, tt, Double::sum); // per VehType

vehicleEnteredLinkTime.remove(vehicleId); //remove from that list.
}
}

private void handleEvent(VehicleEntersTrafficEvent event){
vehicleEnteredLinkTime.put(event.getVehicleId(), event.getTime());
}

@Override public void handleEvent(Event event) {
if (event instanceof CarrierTourStartEvent carrierTourStartEvent) {
handleEvent(carrierTourStartEvent);
} else if (event instanceof CarrierTourEndEvent carrierTourEndEvent) {
handleEvent(carrierTourEndEvent);
} else if (event instanceof LinkEnterEvent linkEnterEvent) {
handleEvent(linkEnterEvent);
} else if (event instanceof LinkLeaveEvent linkLeaveEvent) {
handleEvent(linkLeaveEvent);
} else if (event instanceof VehicleLeavesTrafficEvent vehicleLeavesTrafficEvent) {
handleEvent(vehicleLeavesTrafficEvent);
} else if (event instanceof VehicleEntersTrafficEvent vehicleEntersTrafficEvent) {
handleEvent(vehicleEntersTrafficEvent);
}
}

void writeTravelTimeAndDistance(String analysisOutputDirectory, Scenario scenario) throws IOException {
void writeTravelTimeAndDistancePerVehicle(String analysisOutputDirectory, Scenario scenario) throws IOException {
log.info("Writing out Time & Distance & Costs ... perVehicle");
//Travel time and distance per vehicle
String fileName = analysisOutputDirectory + "TimeDistance_perVehicle.tsv";

BufferedWriter bw1 = new BufferedWriter(new FileWriter(fileName));

//Write headline:
bw1.write("vehicleId \t carrierId \t vehicleTypeId \t tourId \t tourDuration[s] \t travelDistance[m] \t " +
"costPerSecond[EUR/s] \t costPerMeter[EUR/m] \t fixedCosts[EUR] \t varCostsTime[EUR] \t varCostsDist[EUR] \t totalCosts[EUR]");
bw1.write("vehicleId \t carrierId \t vehicleTypeId \t tourId \t "
+ "tourDuration[s] \t tourDuration[h] \t"
+ "travelDistance[m] \t travelDistance[km] \t " +
"travelTime[s] \t travelTime[h] \t" +
"costPerSecond[EUR/s] \t costPerMeter[EUR/m] \t fixedCosts[EUR] \t varCostsTime[EUR] \t varCostsDist[EUR] \t totalCosts[EUR]");
bw1.newLine();

for (Id<Vehicle> vehicleId : vehicleId2VehicleType.keySet()) {

final Double durationInSeconds = vehicleId2TourDuration.get(vehicleId);
final Double distanceInMeters = vehicleId2TourLength.get(vehicleId);
final Double travelTimeInSeconds = vehicleId2TravelTime.get(vehicleId);


final VehicleType vehicleType = VehicleUtils.findVehicle(vehicleId, scenario).getType();
final Double costsPerSecond = vehicleType.getCostInformation().getCostsPerSecond();
Expand All @@ -141,7 +193,14 @@ void writeTravelTimeAndDistance(String analysisOutputDirectory, Scenario scenari
bw1.write("\t" + vehicleId2TourId.get(vehicleId));

bw1.write("\t" + durationInSeconds);
bw1.write("\t" + durationInSeconds /3600);

bw1.write("\t" + distanceInMeters);
bw1.write("\t" + distanceInMeters/1000);

bw1.write("\t" + travelTimeInSeconds);
bw1.write("\t" + travelTimeInSeconds /3600);

bw1.write("\t" + costsPerSecond);
bw1.write("\t" + costsPerMeter);
bw1.write("\t" + fixedCost);
Expand All @@ -161,7 +220,6 @@ void writeTravelTimeAndDistancePerVehicleType(String analysisOutputDirectory, Sc
log.info("Writing out Time & Distance & Costs ... perVehicleType");

//----- All VehicleTypes in CarriervehicleTypes container. Used so that even unused vehTypes appear in the output

TreeMap<Id<VehicleType>, VehicleType> vehicleTypesMap = new TreeMap<>(CarriersUtils.getCarrierVehicleTypes(scenario).getVehicleTypes());
//For the case that there are additional vehicle types found in the events.
for (VehicleType vehicleType : vehicleId2VehicleType.values()) {
Expand All @@ -171,34 +229,39 @@ void writeTravelTimeAndDistancePerVehicleType(String analysisOutputDirectory, Sc
String fileName = analysisOutputDirectory + "TimeDistance_perVehicleType.tsv";

BufferedWriter bw1 = new BufferedWriter(new FileWriter(fileName));

//Write headline:
bw1.write("vehicleTypeId \t nuOfVehicles \t SumOfTourDuration[s] \t SumOfTravelDistances[m] \t " +
bw1.write("vehicleTypeId \t nuOfVehicles \t " +
"SumOfTourDuration[s] \t SumOfTourDuration[h] \t" +
"SumOfTravelDistances[m] \t SumOfTravelDistances[km] \t " +
"SumOfTravelTime[s] \t SumOfTravelTime[h] \t" +
"costPerSecond[EUR/s] \t costPerMeter[EUR/m] \t fixedCosts[EUR/veh] \t" +
"varCostsTime[EUR] \t varCostsDist[EUR] \t fixedCosts[EUR] \t totalCosts[EUR]");
bw1.newLine();


for (VehicleType vehicleType : vehicleTypesMap.values()) {

long nuOfVehicles = vehicleId2VehicleType.values().stream().filter(vehType -> vehType.getId() == vehicleType.getId()).count();

final Double costRatePerSecond = vehicleType.getCostInformation().getCostsPerSecond();
final Double costRatePerMeter = vehicleType.getCostInformation().getCostsPerMeter();
final Double fixedCostPerVeh = vehicleType.getCostInformation().getFixedCosts();

final Double sumOfDurationInSeconds = vehicleTypeId2SumOfDuration.getOrDefault(vehicleType.getId(), 0.);
final Double sumOfTourDurationInSeconds = vehicleTypeId2SumOfTourDuration.getOrDefault(vehicleType.getId(), 0.);
final Double sumOfDistanceInMeters = vehicleTypeId2Mileage.getOrDefault(vehicleType.getId(), 0.);
final Double sumOfTravelTimeInSeconds = vehicleTypeId2TravelTime.getOrDefault(vehicleType.getId(), 0.);

final double sumOfVarCostsTime = sumOfDurationInSeconds * costRatePerSecond;
final double sumOfVarCostsTime = sumOfTourDurationInSeconds * costRatePerSecond;
final double sumOfVarCostsDistance = sumOfDistanceInMeters * costRatePerMeter;
final double sumOfFixCosts = nuOfVehicles * fixedCostPerVeh;

bw1.write(vehicleType.getId().toString());

bw1.write("\t" + nuOfVehicles);
bw1.write("\t" + sumOfDurationInSeconds);
bw1.write("\t" + sumOfTourDurationInSeconds);
bw1.write("\t" + sumOfTourDurationInSeconds / 3600);
bw1.write("\t" + sumOfDistanceInMeters);
bw1.write("\t" + sumOfDistanceInMeters / 1000);
bw1.write("\t" + sumOfTravelTimeInSeconds);
bw1.write("\t" + sumOfTravelTimeInSeconds / 3600);
bw1.write("\t" + costRatePerSecond);
bw1.write("\t" + costRatePerMeter);
bw1.write("\t" + fixedCostPerVeh);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public void runAnalysis() throws IOException {

log.info("Analysis completed.");
log.info("Writing output...");
freightTimeAndDistanceAnalysisEventsHandler.writeTravelTimeAndDistance(analysisOutputDirectory, scenario);
freightTimeAndDistanceAnalysisEventsHandler.writeTravelTimeAndDistancePerVehicle(analysisOutputDirectory, scenario);
freightTimeAndDistanceAnalysisEventsHandler.writeTravelTimeAndDistancePerVehicleType(analysisOutputDirectory, scenario);
carrierLoadAnalysis.writeLoadPerVehicle(analysisOutputDirectory, scenario);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
vehicleId carrierId vehicleTypeId tourId tourDuration[s] travelDistance[m] costPerSecond[EUR/s] costPerMeter[EUR/m] fixedCosts[EUR] varCostsTime[EUR] varCostsDist[EUR] totalCosts[EUR]
vehicleId carrierId vehicleTypeId tourId tourDuration[s] tourDuration[h] travelDistance[m] travelDistance[km] travelTime[s] travelTime[h] costPerSecond[EUR/s] costPerMeter[EUR/m] fixedCosts[EUR] varCostsTime[EUR] varCostsDist[EUR] totalCosts[EUR]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
vehicleTypeId nuOfVehicles SumOfTourDuration[s] SumOfTravelDistances[m] costPerSecond[EUR/s] costPerMeter[EUR/m] fixedCosts[EUR/veh] varCostsTime[EUR] varCostsDist[EUR] fixedCosts[EUR] totalCosts[EUR]
light 0 0.0 60000.0 0.008 4.7E-4 84.0 0.0 28.2 0.0 28.2
vehicleTypeId nuOfVehicles SumOfTourDuration[s] SumOfTourDuration[h] SumOfTravelDistances[m] SumOfTravelDistances[km] SumOfTravelTime[s] SumOfTravelTime[h] costPerSecond[EUR/s] costPerMeter[EUR/m] fixedCosts[EUR/veh] varCostsTime[EUR] varCostsDist[EUR] fixedCosts[EUR] totalCosts[EUR]
light 0 0.0 0.0 60000.0 60.0 8040.0 2.2333333333333334 0.008 4.7E-4 84.0 0.0 28.2 0.0 28.2

0 comments on commit cf76818

Please sign in to comment.