Skip to content

Instantly share code, notes, and snippets.

@owstron
Created February 11, 2019 15:59
Show Gist options
  • Select an option

  • Save owstron/3f51419462209cc6269115241b5e7898 to your computer and use it in GitHub Desktop.

Select an option

Save owstron/3f51419462209cc6269115241b5e7898 to your computer and use it in GitHub Desktop.
4-2 Traffic_Simulation.ipynb
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "4-2 Traffic_Simulation.ipynb",
"version": "0.3.2",
"provenance": [],
"collapsed_sections": [],
"include_colab_link": true
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/nik1997/3f51419462209cc6269115241b5e7898/4-2-traffic_simulation.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"metadata": {
"id": "YqeS1T6T5i-U",
"colab_type": "code",
"colab": {}
},
"cell_type": "code",
"source": [
"# All imports\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "fI1oCkBE5i-v",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"## Rules for updating the simulation\n",
"- Acceleration to v_max (value 5): if *v* of a vehical is lower than v_max and the distance to next car is larger than v+1, the speed will be v→v+1\n",
"- Slowing down: if next vehicle at site i +j (with j ≤v), it reduces speed to j-1\n",
"- Randomization: with prob p, for v >0, do v→ v-1\n",
"- Car motion: move vehical, *v sites*"
]
},
{
"metadata": {
"id": "dgGuM4b65i-x",
"colab_type": "code",
"colab": {}
},
"cell_type": "code",
"source": [
"class TrafficSimulation:\n",
" '''\n",
" Simualtes the traffic flow\n",
" '''\n",
" \n",
" def __init__(self, road_length=100, traffic_density=0.03, max_velocity=5, \n",
" p_slowing=0.5, fixed_point = 0):\n",
" '''\n",
" Initializing Traffic Simulator\n",
" \n",
" Inputs:\n",
" \n",
" * road_length (int) length of roadLor number of cells. Default:100\n",
" \n",
" * traffic_density (float) the proportion of road covered by\n",
" traffic. Default:0.03\n",
" \n",
" * max_velocity (int) maximum velocity of the car. Default:5\n",
" \n",
" * p_slowing (float) probability of a car slowing down\n",
" \n",
" '''\n",
" \n",
" self.road_length = road_length\n",
" \n",
" if traffic_density > 1:\n",
" raise Exception('Traffic density greater than 1')\n",
" \n",
" self.traffic_density = traffic_density\n",
" self.max_velocity = max_velocity\n",
" self.p_slowing = p_slowing\n",
" \n",
" self.current_state = self.initialize_traffic()\n",
" self.display_state = list(self.current_state)\n",
" \n",
" self.fixed_point = fixed_point #Stores the position where we are measuring average flow\n",
" self.total_flow = 0 # stores the number of cars flowed through the fixed point\n",
" self.qs = []\n",
" \n",
" \n",
" def initialize_traffic(self):\n",
" '''\n",
" Creates an array with current state of simulation with matching traffic\n",
" density\n",
" '''\n",
"\n",
" cars = np.random.choice(self.road_length, replace=False,\n",
" size=int(self.road_length * self.traffic_density))\n",
" \n",
" states = np.full(self.road_length, -1)\n",
" \n",
" for car_index in cars:\n",
" speed = np.random.randint(0, self.max_velocity + 1)\n",
" states[car_index] = speed\n",
" \n",
" return states\n",
" \n",
" \n",
" def update(self):\n",
" '''\n",
" Updates the simulation by one time step\n",
" '''\n",
" next_state = np.full(self.road_length, -1) \n",
" next_moves = np.full(self.road_length, -1)\n",
" # stores the next state and position of all cars\n",
" \n",
"\n",
" \n",
" for i in range(self.road_length):\n",
"\n",
" if self.current_state[i] != -1:\n",
" \n",
" \n",
" # if the current cell is a car\n",
" cur_v = self.current_state[i]\n",
" \n",
" # Step 1: Acceleration: by default increasing it 1\n",
" if cur_v < self.max_velocity:\n",
" # Increasing the current velocity directly if lower than max_velocity\n",
" # Since will will check and decrease the speed by checking neighbors in next step\n",
" cur_v += 1\n",
" \n",
" \n",
" # Step 2: Slowing Down car based on neighbors\n",
" for step in range(1, cur_v + 1):\n",
" if self.current_state[(i+step) % self.road_length] != -1:\n",
" cur_v = step - 1\n",
" break\n",
" \n",
" \n",
" # Step 3: \n",
" # Slowing down the car based on random probability if the car's\n",
" # velocity is faster than 0\n",
" if np.random.random() <= self.p_slowing and cur_v > 0: \n",
" cur_v -= 1\n",
" \n",
" next_moves[i] = cur_v # Updates the new velocity of cars\n",
" \n",
" \n",
" # Step 4: \n",
" \n",
" # Moving the car based on velocity\n",
" \n",
" final_pos = (i + cur_v) % self.road_length\n",
" next_state[final_pos] = final_pos\n",
"\n",
"\n",
" self.display_state = next_moves\n",
" self.current_state = next_state # Moved cars and put it in velocity of cars\n",
" \n",
" self.calc_flow()\n",
" \n",
" \n",
" \n",
" def calc_flow(self):\n",
"# if self.display_state[self.fixed_point] == -1 and self.display_state[self.fixed_point + 1] == -1:\n",
"# for i in range(self.max_velocity, 0, -1):\n",
"# if self.display_state[self.fixed_point - i] != -1 and self:\n",
"# self.total_flow += 1\n",
" \n",
" counter = 0\n",
" for i in range(1, self.max_velocity): \n",
" if self.display_state[-i] >= i: \n",
" counter += 1\n",
" self.qs.append(counter)\n",
" \n",
" def calc_avg_flow(self):\n",
" '''\n",
" Calculates average traffic flow of cars at the fixed point\n",
" \n",
" Input:\n",
" \n",
" Output:\n",
" \n",
" (float) the average flow of the car at a certain point\n",
" '''\n",
" \n",
"# return self.total_flow / time_period\n",
"\n",
" if len(self.qs) == 0:\n",
" return 0\n",
"\n",
" return sum(self.qs) / len(self.qs)\n",
" \n",
" def display(self):\n",
" '''\n",
" Displays the current state of simulation, the cars are represented by\n",
" a number greater than or equals to 0. The number represents the velocity\n",
" of car.\n",
" The empty spaces is shown as dots.\n",
" \n",
" Input:\n",
" \n",
" * states (array) The array with the next moving state of the cars\n",
" '''\n",
" print(''.join(['.' if x == -1 else str(x) for x in self.display_state]))"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "_f9yVm5f5i-4",
"colab_type": "code",
"outputId": "7b413e5f-86b4-4e25-905e-880a6bf7fba3",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 476
}
},
"cell_type": "code",
"source": [
"#displays right before you move\n",
"\n",
"# Simulation with parameters:\n",
"# np.random.seed(5)\n",
"road_length = 100\n",
"traffic_density = 0.5\n",
"max_velocity = 5\n",
"p_slowing = 0.01\n",
"\n",
"sim = TrafficSimulation(road_length, traffic_density, max_velocity, p_slowing)\n",
"\n",
"# Show initial states\n",
"print('Initial State')\n",
"sim.display()\n",
"\n",
"print('-'*20)\n",
"print('Simulation Starts')\n",
"print('-'*20)\n",
"N = 20\n",
"for i in range(N):\n",
" sim.update()\n",
" sim.display()\n",
"\n",
"print(sim.total_flow)\n",
"\n",
"print(sim.calc_avg_flow())\n",
"\n",
"\n",
"# sim.update()\n",
"# sim.display()\n",
"\n",
"# sim.update()\n",
"# sim.display()\n"
],
"execution_count": 0,
"outputs": [
{
"output_type": "stream",
"text": [
"Initial State\n",
"....22.4.....2.1.....0144.3..2.5.03313541..0.01.4113.2.2..5105..5.1.10144.2.5..3......4.0...354.1.5.\n",
"--------------------\n",
"Simulation Starts\n",
"--------------------\n",
"....01.5.....1.2.....0001.2..1.1.00000002..1.01.0001.1.2..0002..1.1.00001.1.2..4......1.1...001.1.5.\n",
"...01.5.....1.2..3...001.2..1.1.00000002..1.01.0001.1.2..0002..1.1.00001.1.2..4....3...1.2..01.1.5..\n",
"..01.5.....1.2..3...001.2..1.1.00000002..1.01.0001.1.2..0002..1.1.00001.1.2..4....3...1.2..01.1.5...\n",
".01.5.....1.2..3...001.2..1.1.00000002..1.01.0001.1.2..0002..1.1.00001.1.2..4....3...1.2..01.1.5....\n",
"01.4.....1.2..3...001.2..1.1.00000002..1.01.0001.1.2..0002..1.1.00001.1.2..4....3...1.2..01.1.5.....\n",
"1.3....2..2..3...001.2..1.1.00000002..1.01.0001.1.2..0002..1.1.00001.1.2..4....3...1.2..01.1.5.....0\n",
".2...3...2..3...001.2..1.1.00000002..1.01.0001.1.2..0002..1.1.00001.1.2..4....3...1.2..01.1.5.....01\n",
"1..4....2..3...001.2..1.1.00000002..1.01.0001.1.2..0002..1.1.00001.1.2..4....3...1.2..01.1.5.....01.\n",
".2.....2..3...001.2..1.1.00000002..1.01.0001.1.2..0002..1.1.00001.1.2..4....3...1.2..01.1.5.....01.1\n",
"1..4.....3...001.2..1.1.00000002..1.01.0001.1.2..0002..1.1.00001.1.2..4....3...1.2..01.1.5.....01.1.\n",
".2.....4....001.2..1.1.00000002..1.01.0001.1.2..0002..1.1.00001.1.2..4....3...1.2..01.1.5.....01.1.1\n",
"1..4.......001.2..1.1.00000002..1.01.0001.1.2..0002..1.1.00001.1.2..4....3...1.2..01.1.5.....01.1.1.\n",
".2.....3...01.2..1.1.00000002..1.01.0001.1.2..0002..1.1.00001.1.2..4....3...1.2..01.1.5.....01.1.1.1\n",
"1..4......01.2..1.1.00000002..1.01.0001.1.2..0002..1.1.00001.1.2..4....3...1.2..01.1.5.....01.1.1.1.\n",
".2.....2..1.2..1.1.00000002..1.01.0001.1.2..0002..1.1.00001.1.2..4....3...1.2..01.1.5.....01.1.1.1.1\n",
"1..4.....1.2..1.1.00000002..1.01.0001.1.2..0002..1.1.00001.1.2..4....3...1.2..01.1.5.....01.1.1.1.1.\n",
".2.....2..2..1.1.00000002..1.01.0001.1.2..0002..1.1.00001.1.2..4....3...1.2..01.1.5.....01.1.1.1.1.1\n",
"1..4.....2..1.1.00000002..1.01.0001.1.2..0002..1.1.00001.0.2..4....3...1.2..01.1.5.....01.1.1.1.1.1.\n",
".2.....3...1.1.00000002..1.01.0001.1.2..0002..1.1.00001.03...4....3...1.2..01.1.5.....01.1.1.1.1.1.1\n",
"1..4......1.1.00000002..1.01.0001.1.2..0002..1.1.00001.03...4....3...1.2..01.1.5.....01.1.1.1.1.1.1.\n",
"0\n",
"0.5\n"
],
"name": "stdout"
}
]
},
{
"metadata": {
"id": "nNKlMLSACxDq",
"colab_type": "code",
"outputId": "8e10a09e-4e63-41ab-a386-0287feff6870",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 381
}
},
"cell_type": "code",
"source": [
"# Plotting the flow.\n",
"arr_density = np.linspace(0, 1, num=50)\n",
"\n",
"arr_avg_flow = []\n",
"\n",
"num_timesteps = 500 #number of timesteps for each simulation\n",
"\n",
"road_length = 100\n",
"max_velocity = 1\n",
"p_slowing = 0.5\n",
"print('Simulation started: ')\n",
"for density in arr_density:\n",
"\n",
" sim = TrafficSimulation(road_length, density, max_velocity, p_slowing)\n",
" \n",
" for i in range(num_timesteps):\n",
" sim.update()\n",
" \n",
" arr_avg_flow.append(sim.calc_avg_flow())\n",
" \n",
"\n",
"\n",
"plt.scatter(arr_density, arr_avg_flow)"
],
"execution_count": 0,
"outputs": [
{
"output_type": "stream",
"text": [
"Simulation started: \n"
],
"name": "stdout"
},
{
"output_type": "execute_result",
"data": {
"text/plain": [
"<matplotlib.collections.PathCollection at 0x7f2d44c44710>"
]
},
"metadata": {
"tags": []
},
"execution_count": 77
},
{
"output_type": "display_data",
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 576x396 with 1 Axes>"
]
},
"metadata": {
"tags": []
}
}
]
},
{
"metadata": {
"id": "rv_QYd3KHQz8",
"colab_type": "code",
"outputId": "6465b485-3128-494b-d413-6687abfbeca5",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 34
}
},
"cell_type": "code",
"source": [
"print(arr_avg_flow)"
],
"execution_count": 0,
"outputs": [
{
"output_type": "stream",
"text": [
"[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n"
],
"name": "stdout"
}
]
},
{
"metadata": {
"id": "Yr6ZHkZQ5i_H",
"colab_type": "code",
"outputId": "37ca2046-3b9d-4d23-e75f-15cccf7264eb",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 442
}
},
"cell_type": "code",
"source": [
"# Simulation with parameters:\n",
"road_length = 100\n",
"traffic_density = 0.1\n",
"max_velocity = 5\n",
"p_slowing = 0.5\n",
"\n",
"sim = TrafficSimulation(road_length, traffic_density, max_velocity, p_slowing)\n",
"\n",
"# Show initial states\n",
"print('Initial State')\n",
"sim.display()\n",
"\n",
"print('-'*20)\n",
"print('Simulation Starts')\n",
"print('-'*20)\n",
"for i in range(20):\n",
" sim.update()\n",
" sim.display()"
],
"execution_count": 0,
"outputs": [
{
"output_type": "stream",
"text": [
"Initial State\n",
".0.........3........55.20.......1...............3.............4.........4...........................\n",
"--------------------\n",
"Simulation Starts\n",
"--------------------\n",
".0.........4........01.00.......1...............3.............4.........5...........................\n",
".1.............5....0.001........2.................3..............5..........4......................\n",
"..2.................1.11.1.........3..................4................5.........5..................\n",
"....2................2..1.1...........4...................5.................5.........5.............\n",
"......2................0.1.2..............5....................4.................4.........4........\n",
"........3..............1..2..3.................4...................5.................5.........5....\n",
"4..........3............1...3...3..................4....................4.................4.........\n",
"....5.........3..........2.....4...4...................5....................4.................4.....\n",
".........4.......4.........2...........4....................5...................4.................5.\n",
"...5.........4.......5.......2.............4.....................4..................5...............\n",
"........4........5........5....3...............4.....................5...................5..........\n",
"............5.........4...........4................5......................5...................4.....\n",
".................4........5...........5.................4......................4..................5.\n",
"...4.................4.........4...........5................5......................5................\n",
".......4.................4.........5............5................5......................4...........\n",
"...........5.................5..........5............4................5.....................5.......\n",
"................5.................4..........5...........4.................4.....................4..\n",
".5...................4................5...........4..........4.................5....................\n",
"......5..................4.................5..........4..........4..................4...............\n",
"...........4.................5..................4.........4..........5..................4...........\n"
],
"name": "stdout"
}
]
},
{
"metadata": {
"id": "tOWGkA_l5pEh",
"colab_type": "code",
"outputId": "ce831e20-97b2-4585-9822-b4c96a675e79",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 442
}
},
"cell_type": "code",
"source": [
"# Simulation with parameters:\n",
"road_length = 100\n",
"traffic_density = 0.4\n",
"max_velocity = 5\n",
"p_slowing = 0.5\n",
"\n",
"sim = TrafficSimulation(road_length, traffic_density, max_velocity, p_slowing)\n",
"\n",
"# Show initial states\n",
"# Show initial states\n",
"print('Initial State')\n",
"sim.display()\n",
"\n",
"print('-'*20)\n",
"print('Simulation Starts')\n",
"print('-'*20)\n",
"for i in range(20):\n",
" sim.update()\n",
" sim.display()"
],
"execution_count": 0,
"outputs": [
{
"output_type": "stream",
"text": [
"Initial State\n",
"...2....0.3.......2..40...1.0.30..5..4.4......4..55.14....5...3.20.0.....2.40.54.5.0..1.5.4....11...\n",
"--------------------\n",
"Simulation Starts\n",
"--------------------\n",
"...3....0.3.......2..01...2.1.00..1..0.4......1..01.05....2...1.01.0.....0.01.01.1.1..1.1.4....01...\n",
"......0.0....3......00.2.....000...2.1.....2...2.1.01.......2..01.00.....0.0.00.1.1.1..1.1....00.2..\n",
"......0.0.......4...10...3...011......1......2....00.2........00.010.....1.0.00..2.2.2..1.1...01...3\n",
"..3...1.1............1......00..1......2.......2..01...2......11.0.1......01.00........0.2.1..1.2...\n",
".....0.1.1............2.....01...2.......2.......01.1....2......01..2.....1.001........1....1..1..3.\n",
".4...1..1.2.............3...0.2....3.......3.....0.2.2.....3....1.2...3....010.2........1....1..1...\n",
"......2..1..3..............01...3.....4.......2..1.....2......1..2..3....1.1.0...2.......2....2..1..\n",
"........0.1....4...........0.1.....4......5.....1.2......3.....1...2...2..2.01.....3.......2....1.1.\n",
"........1..2.......4.......1..2........4.......0.2..3.......4...1....2...3..0.1.......4......3...2.1\n",
"1........1...3.........5....2...2..........2...0...2...3.........2.....2....1..1..........4.....3...\n",
".2........1.....4.............2...3..........1.1.....2....4........2.....2...2..1.............5....1\n",
"2..2.......2........5...........3....4........2.2......3......4......2.....3...0.2..................\n",
"..2..3.......2...........5.........3.....5........3.......4.......4....2......00...2................\n",
"....2...4......2..............5.......3.......5......3........5.......1..2....00.....2..............\n",
"......3.....4....3.................4.....3.........4....4..........3...2...3..00.......2............\n",
".........3......3...3..................5....3..........4....4.........2..2....11.........2..........\n",
"............3......3...3.......................4...........5....4.......3..2....1..........3........\n",
"...............4......3...4........................4................4........3...1............4.....\n",
"...................4.....4....5........................4................4.......1.1...............4.\n",
"..4....................5.....5.....5.......................5................4....2.1................\n"
],
"name": "stdout"
}
]
},
{
"metadata": {
"id": "slyYp_m77oqK",
"colab_type": "code",
"colab": {}
},
"cell_type": "code",
"source": [
"# From Class Session!\n",
"\n",
"class TrafficSimulation:\n",
"\n",
" def __init__(self, length=100, car_density=0.2, slow_down_prob=0.5, max_speed=5):\n",
" '''\n",
" Create a new traffic simulation object. Cars are distributed randomly\n",
" along the road and start with random velocities.\n",
"\n",
" Inputs:\n",
"\n",
" length (int) The number of cells in the road. Default: 100.\n",
"\n",
" car_density (float) The fraction of cells that have a car on them.\n",
" Default: 0.2.\n",
"\n",
" slow_down_prob (float) The probability that a car will randomly\n",
" slow down by 1 during an update step. Default: 0.5.\n",
"\n",
" max_speed (int) The maximum speed in car cells per update step.\n",
" Default: 5.\n",
" '''\n",
" self.length = length\n",
" self.car_density = car_density\n",
" self.max_speed = max_speed\n",
" self.slow_down_prob = slow_down_prob\n",
"\n",
" # Track the time steps and total number of cars that passed the simulation\n",
" # boundary to estimate average traffic flow.\n",
" self.time_step = 0\n",
" self.cumulative_traffic_flow = 0\n",
"\n",
" random_indexes = np.random.choice(\n",
" range(self.length),\n",
" size=int(round(car_density * self.length)),\n",
" replace=False)\n",
" self.state = -np.ones(self.length, dtype=int) # -1 means empty cell\n",
" self.state[random_indexes] = np.random.randint(\n",
" 0, self.max_speed + 1, size=len(random_indexes))\n",
"\n",
" def step(self):\n",
" '''\n",
" Advance one time step in the simulation.\n",
" '''\n",
"\n",
" # Update car velocities.\n",
" for i in range(self.length):\n",
" if self.state[i] != -1:\n",
" distance = 1 # The number of empty cells between this car and the next plus 1\n",
" while self.state[(i + distance) % self.length] == -1:\n",
" distance += 1\n",
" # Acceleration\n",
" if self.state[i] < self.max_speed:\n",
" self.state[i] += 1\n",
" # Deceleration\n",
" if self.state[i] >= distance:\n",
" self.state[i] = distance - 1\n",
" # Randomization\n",
" if (self.state[i] > 0) and (np.random.uniform() < self.slow_down_prob):\n",
" self.state[i] -= 1\n",
"\n",
" if display:\n",
" self.display()\n",
"\n",
" # Move cars forward using their new velocities\n",
" new_state = -np.ones(self.length, dtype=int)\n",
" for i in range(self.length):\n",
" if self.state[i] != -1:\n",
" new_state[(i + self.state[i]) % self.length] = self.state[i]\n",
" self.state = new_state\n",
"\n",
" # Update time and traffic flow\n",
" self.time_step += 1\n",
" for i in range(self.max_speed):\n",
" if self.state[i] > i:\n",
" self.cumulative_traffic_flow += 1\n",
"\n",
" def display(self):\n",
" '''\n",
" Print out the current state of the simulation.\n",
" '''\n",
" print(''.join('.' if x == -1 else str(x) for x in self.state))"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "xjNRmaHapmpA",
"colab_type": "code",
"outputId": "e7905a59-372f-4d4c-ef8b-b0afe42e8fa9",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 364
}
},
"cell_type": "code",
"source": [
"import matplotlib.pyplot as plt\n",
"\n",
"display = False\n",
"\n",
"density = np.arange(0,0.8,0.01)\n",
"\n",
"\n",
"x = []\n",
"y = []\n",
"num_simulation = 100\n",
"\n",
"# Conduct simulation\n",
"for d in density:\n",
" for i in range(num_simulation):\n",
" # reset sim:\n",
" t = TrafficSimulation(car_density = d)\n",
" for _ in range(200):\n",
" t.step()\n",
"\n",
" y.append(t.cumulative_traffic_flow/t.time_step)\n",
" x.append(d)\n",
"\n",
"plt.plot(x, y)"
],
"execution_count": 0,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x7f2d451e1438>]"
]
},
"metadata": {
"tags": []
},
"execution_count": 83
},
{
"output_type": "display_data",
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 576x396 with 1 Axes>"
]
},
"metadata": {
"tags": []
}
}
]
},
{
"metadata": {
"id": "7ejiKo-_qYOf",
"colab_type": "code",
"colab": {}
},
"cell_type": "code",
"source": [
"import numpy as np\n",
"import scipy.stats\n",
"\n",
"# Use percentile to find the confidencce interval and plot them\n"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "7YmajYGfA9HW",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"Detect traffic flow or traffic motion\n",
"\n",
"n_i,i+1 (t) = 0 if no movement from i to i + 1\n",
"\n",
"fixed_point\n",
"\n",
"When moving in current state\n",
"\n",
"if fixed_point is between final_pos and i, then, there is a movement\n"
]
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment