{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Taxi / Shared mobility" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The standard vehicles (added by default `addVehicle` or `adddemand`) in UXsim are a kind of privately owned vehicles: They travel from origin to destination and disappear. \n", "\n", "In this demonstration, we explain how to represent taxi-like (or *shared mobility* if you want a cool name) vehicles that repeatedly transport multiple passengers. Such taxi can be added by `addVehicle` with `mode=\"taxi\"` option. Furthermore, the passenger-to-taxi matching problem is handled by `uxsim.TaxiHandler` submodule.\n", "\n", "Let's define a grid shaped network scenario." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", "%load_ext autoreload\n", "%autoreload 2" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from pylab import *\n", "from uxsim import *\n", "from uxsim.TaxiHandler import *\n", "\n", "# World definition\n", "tmax = 7200\n", "deltan = 5\n", "W = World(\n", " name=\"\",\n", " deltan=deltan,\n", " tmax=tmax,\n", " print_mode=1, save_mode=1, show_mode=1,\n", " random_seed=0,\n", ")\n", "\n", "# Scenario definition: grid network\n", "#deploy nodes as an imax x jmax grid\n", "imax = 6\n", "jmax = 6\n", "nodes = {}\n", "for i in range(imax):\n", " for j in range(jmax):\n", " nodes[i,j] = W.addNode(f\"n{(i,j)}\", i, j, flow_capacity=1.6)\n", "\n", "#create links between neighborhood nodes\n", "links = {}\n", "for i in range(imax):\n", " for j in range(jmax):\n", " if i != imax-1:\n", " links[i,j,i+1,j] = W.addLink(f\"l{(i,j,i+1,j)}\", nodes[i,j], nodes[i+1,j], length=1000, free_flow_speed=20, number_of_lanes=1)\n", " if i != 0:\n", " links[i,j,i-1,j] = W.addLink(f\"l{(i,j,i-1,j)}\", nodes[i,j], nodes[i-1,j], length=1000, free_flow_speed=20, number_of_lanes=1)\n", " if j != jmax-1:\n", " links[i,j,i,j+1] = W.addLink(f\"l{(i,j,i,j+1)}\", nodes[i,j], nodes[i,j+1], length=1000, free_flow_speed=20, number_of_lanes=1)\n", " if j != 0:\n", " links[i,j,i,j-1] = W.addLink(f\"l{(i,j,i,j-1)}\", nodes[i,j], nodes[i,j-1], length=1000, free_flow_speed=20, number_of_lanes=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Taxis can be added by `W.addVehicle(origin_node, None, 0, mode=\"taxi\")` as follows. Their behavior is as follows:\n", "\n", "- When a taxi has no job, it circulates the network randomly.\n", "- When a taxi is ordered to serve a passenger, it travels to the origin node of the passenger to pickup, and then travels to the destination to drop-off.\n", "\n", "In addition, we need to define a taxi handler `Handler`. It is responsible to manage trip requests from passengers and give orders to taxis. This time, we use default `TaxiHandler_nearest` that matches a new passenger to their nearest vacant taxi." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "Handler = TaxiHandler_nearest(W)\n", "\n", "n_taxis = 3000\n", "for i in range(int(n_taxis/deltan)):\n", " node = random.choice(list(nodes.values()))\n", " W.addVehicle(node, None, 0, mode=\"taxi\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A passenger' trip request is represented by `TripRequest` class. It can be added by `Handler.add_trip_request(origin_node, destination_node, departure_time)`. In this scenario, they are randomly set as follows." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "n_passengers = 20000\n", "for i in range(int(n_passengers/deltan)):\n", " node1 = random.choice(list(nodes.values()))\n", " node2 = random.choice(list(nodes.values()))\n", " while node1 == node2:\n", " node2 = random.choice(list(nodes.values()))\n", " Handler.add_trip_request(node1, node2, i/n_passengers*deltan*tmax/2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we can execute simulation. During the simulation, `Handler.assign_trip_request_to_taxi()` must be called repeatedly in order to let taxis do their jobs." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "simulation setting:\n", " scenario name: \n", " simulation duration:\t 7200 s\n", " number of vehicles:\t 3000 veh\n", " total road length:\t 120000 m\n", " time discret. width:\t 5 s\n", " platoon size:\t\t 5 veh\n", " number of timesteps:\t 1440\n", " number of platoons:\t 600\n", " number of links:\t 120\n", " number of nodes:\t 36\n", " setup time:\t\t 0.34 s\n", "simulating...\n", " time| # of vehicles| ave speed| computation time\n", " 0 s| 0 vehs| 0.0 m/s| 0.00 s\n", " 600 s| 3000 vehs| 13.3 m/s| 0.77 s\n", " 1200 s| 3000 vehs| 12.6 m/s| 1.44 s\n", " 1800 s| 3000 vehs| 14.4 m/s| 2.11 s\n", " 2400 s| 3000 vehs| 14.2 m/s| 2.88 s\n", " 3000 s| 3000 vehs| 14.2 m/s| 3.56 s\n", " 3600 s| 3000 vehs| 14.3 m/s| 4.25 s\n", " 4200 s| 3000 vehs| 14.3 m/s| 4.79 s\n", " 4800 s| 3000 vehs| 14.2 m/s| 5.32 s\n", " 5400 s| 3000 vehs| 14.6 m/s| 5.86 s\n", " 6000 s| 3000 vehs| 14.2 m/s| 6.35 s\n", " 6600 s| 3000 vehs| 14.1 m/s| 6.86 s\n", " 7195 s| 3000 vehs| 14.5 m/s| 7.36 s\n", " simulation finished\n", "results:\n", " average speed:\t 14.3 m/s\n", " number of completed trips:\t 0 / 0\n" ] } ], "source": [ "# Run the simulation \n", "while W.check_simulation_ongoing():\n", " W.exec_simulation(duration_t = 60)\n", " Handler.assign_trip_request_to_taxi() # for every 60 seconds, the taxi is assgined\n", "\n", "# Results\n", "W.analyzer.print_simple_stats()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that the trip-related stats shown by `W.analyzer.print_simple_stats()` are only for non-taxi trips, so the current one shows 0.\n", "\n", "The summary of taxi transportation can be printed as follows" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "results for taxi transportation:\n", " total trip rquests: 20000\n", " completed trip requests: 20000\n", " completed trip requests ratio: 1.00\n", " average number of completed requests per taxi: 6.67\n", " average waiting time: 84.6\n", " average in-vehicle time: 297.5\n", " average trip time: 382.0\n" ] } ], "source": [ "Handler.print_stats()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also export the trip logs as pandas.Dataframe." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " | orig | \n", "dest | \n", "depart_time | \n", "get_taxi_time | \n", "arrival_time | \n", "travel_time | \n", "waiting_time | \n", "used_taxi | \n", "
---|---|---|---|---|---|---|---|---|
0 | \n", "n(3, 2) | \n", "n(2, 2) | \n", "0.0 | \n", "155 | \n", "210 | \n", "210.0 | \n", "155.0 | \n", "12 | \n", "
1 | \n", "n(1, 5) | \n", "n(4, 5) | \n", "0.9 | \n", "140 | \n", "295 | \n", "294.1 | \n", "139.1 | \n", "164 | \n", "
2 | \n", "n(3, 2) | \n", "n(4, 4) | \n", "1.8 | \n", "55 | \n", "225 | \n", "223.2 | \n", "53.2 | \n", "175 | \n", "
3 | \n", "n(2, 2) | \n", "n(2, 5) | \n", "2.7 | \n", "155 | \n", "310 | \n", "307.3 | \n", "152.3 | \n", "344 | \n", "
4 | \n", "n(2, 0) | \n", "n(1, 0) | \n", "3.6 | \n", "55 | \n", "105 | \n", "101.4 | \n", "51.4 | \n", "101 | \n", "
... | \n", "... | \n", "... | \n", "... | \n", "... | \n", "... | \n", "... | \n", "... | \n", "... | \n", "
3995 | \n", "n(4, 1) | \n", "n(4, 0) | \n", "3595.5 | \n", "3655 | \n", "3715 | \n", "119.5 | \n", "59.5 | \n", "86 | \n", "
3996 | \n", "n(0, 1) | \n", "n(3, 0) | \n", "3596.4 | \n", "3765 | \n", "4005 | \n", "408.6 | \n", "168.6 | \n", "111 | \n", "
3997 | \n", "n(5, 3) | \n", "n(0, 2) | \n", "3597.3 | \n", "3770 | \n", "4330 | \n", "732.7 | \n", "172.7 | \n", "528 | \n", "
3998 | \n", "n(5, 2) | \n", "n(2, 4) | \n", "3598.2 | \n", "3750 | \n", "4040 | \n", "441.8 | \n", "151.8 | \n", "332 | \n", "
3999 | \n", "n(2, 2) | \n", "n(0, 3) | \n", "3599.1 | \n", "3655 | \n", "3840 | \n", "240.9 | \n", "55.9 | \n", "107 | \n", "
4000 rows × 8 columns
\n", "