matsim-org / matsim-code-examples

A repository containing code examples around MATSim
GNU General Public License v3.0
81 stars 178 forks source link

Estimate the total travel time for all the vehicles #1112

Open MadushaSammani opened 4 months ago

MadushaSammani commented 4 months ago

I need to analyze the total travel time for all vehicles.

In each scenario, I try to increase the vehicle count by 10%, 20%, 30%, and so on. Then, I calculated the travel time for each scenario and plotted it in a scatterplot to see how vehicles' estimated travel time varied. My scatterplot shows a linear relationship. Is this correct? I was hoping that, before plotting in, there would be a non-linear relationship.

To calculate the total time to travel, I only considered PersonArrivalEventHandler.

Janekdererste commented 4 months ago

From the top of my head, I would also not expect a linear function. I would expect slowly increasing travel times for a small number of vehicles and then, once the network is congested, I would expect travel times to increase. Something similar to this diagram:

image

Would you mind sharing your Event Handler so that I can take a look? Preferably, as a link to your GitHub repository.

MadushaSammani commented 4 months ago

Thanks a lot. Yes, I am expecting a plot something similar to this. Here I am scharing my event hander.

https://github.com/MadushaSammani/TravelTimeEstimate.git

I do not use absolute time. I used relative time. First person start to travel at 0:0:0. I used only PersonArrivalEventHandler. So I can find the time for last agent to arrive.

Janekdererste commented 4 months ago

Thanks for the code example. I think the script you have written is not calculating what you want.

@Override
    public void handleEvent(PersonArrivalEvent personArrivalEvent) {
        arrival++;
        arrivalTimes.add(new Tuple<Double, Integer>(personArrivalEvent.getTime(), arrival));
    }

your handler stores the event time and a counter. This fails to capture the duration, as you are just storing the time at which the event happened. You could implement something along the following, which stores the departure time with the person id. Then, on arrival, the duration of the leg is calculated and stored in a list. With this, you would be able to plot the travel times by trip number, which are sorted by arrival time.

public class TravelTimeHandler implements PersonDepartureEventHandler, PersonArrivalEventHandler {

    private final Map<Id<Person>, Double> startTimes = new HashMap<>();
    private final List<Double> travelTimes = new ArrayList<>();

    public List<Double> getTravelTimes() {
        return travelTimes;
    }

    @Override
    public void handleEvent(PersonArrivalEvent personArrivalEvent) {
        if (startTimes.containsKey(personArrivalEvent.getPersonId())) {
            var startTime = startTimes.remove(personArrivalEvent.getPersonId());
            var endTime = personArrivalEvent.getTime();
            var travelTime = endTime - startTime;
            travelTimes.add(travelTime);
        }
    }

    @Override
    public void handleEvent(PersonDepartureEvent personDepartureEvent) {
        if (personDepartureEvent.getRoutingMode().equals(TransportMode.car)) {
            startTimes.put(personDepartureEvent.getPersonId(), personDepartureEvent.getTime());
        }
    }
}

Then you can use that handler like the following:

    public static void main(String[] args) {

        var handler = new TravelTimeHandler();
        var manager = EventsUtils.createEventsManager();
        manager.addHandler(handler);
        EventsUtils.readEvents(manager, "/path/to/events.xml.gz");

        for (var travelTime : handler.getTravelTimes()) {
            System.out.println(travelTime);
        }

Another option would be to utilize the trip.csv output. This file should include travel times as a column and you can use which ever tool you are most comfortable with to create a histogram.