diff --git a/.envrc b/.envrc deleted file mode 100644 index 94840b3..0000000 --- a/.envrc +++ /dev/null @@ -1 +0,0 @@ -layout python3 diff --git a/.gitignore b/.gitignore index 574ba10..606512b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .direnv/ __pycache__/ +.envrc diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..9b1c5e1 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +traffic-simulation \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..21109db --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..25ff64a --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/traffic-simulation.iml b/.idea/traffic-simulation.iml new file mode 100644 index 0000000..dddbc23 --- /dev/null +++ b/.idea/traffic-simulation.iml @@ -0,0 +1,16 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..f3e1cba --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,759 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1434113433382 + + + 1434116675477 + + + 1434144950039 + + + 1434150796784 + + + 1434153638242 + + + 1434153908682 + + + 1434155604866 + + + 1434168651393 + + + 1434171526488 + + + 1434224173455 + + + 1434228959580 + + + 1434229488350 + + + 1434244040194 + + + 1434253753084 + + + 1434253789888 + + + 1434293201706 + + + 1434293301916 + + + 1434297376282 + + + 1434299434223 + + + 1434306319512 + + + 1434306593213 + + + 1434306657915 + + + 1434315759989 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.ipynb_checkpoints/Traffic Simulation Plots-checkpoint.ipynb b/.ipynb_checkpoints/Traffic Simulation Plots-checkpoint.ipynb new file mode 100644 index 0000000..a8fd18d --- /dev/null +++ b/.ipynb_checkpoints/Traffic Simulation Plots-checkpoint.ipynb @@ -0,0 +1,137 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import random\n", + "import statistics as st\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "from simulation import Sim\n", + "from itertools import count\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "sim = Sim()\n", + "sim.time = 60\n", + "meta_data = sim.main()\n", + "def annoy(data):\n", + " x_list = []\n", + " y_list = []\n", + " speed = []\n", + " \n", + " x_list = x_list + [x for x,y,z in data]\n", + " y_list = y_list + [y for x,y,z in data]\n", + " speed = speed + [z for x,y,z in data]\n", + " return x_list, y_list, speed\n", + "x, y, speed = annoy(meta_data)\n", + "\n", + "average_speed = (st.mean(speed) * 60**2) / 1000\n", + "stan_dev = (st.stdev(speed) * 60**2) / 1000\n", + "s_limit = average_speed + stan_dev\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nJjeyB05gtQAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.xlabel(\"Time in Seconds\\n\\n Average Speed: {} Kilometers per hour\\n \\\n", + " Suggested Speed Limit: {} Kilometers per hour \".format(average_speed, s_limit))\n", + "plt.ylabel(\"Distance\")\n", + "plt.title(\"Traffic Flow on 1 km Road\")\n", + "colors = [np.random.choice([\"blue\", \"green\"]) for _ in x]\n", + "plt.scatter(y, x, s=1, c=colors, marker=\"|\")\n", + "\n", + "\n", + "\n", + "\n", + "plt.show() " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##Findings \n", + "#### By looking at my data I have come to the conclusion that a lower speed limit is generally better in normal mode on this road because otherwise the cars will group up too much trying to match the car in fronts speed." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.4.2" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/Traffic Simulation Plots.ipynb b/Traffic Simulation Plots.ipynb new file mode 100644 index 0000000..a8fd18d --- /dev/null +++ b/Traffic Simulation Plots.ipynb @@ -0,0 +1,137 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import random\n", + "import statistics as st\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "from simulation import Sim\n", + "from itertools import count\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "sim = Sim()\n", + "sim.time = 60\n", + "meta_data = sim.main()\n", + "def annoy(data):\n", + " x_list = []\n", + " y_list = []\n", + " speed = []\n", + " \n", + " x_list = x_list + [x for x,y,z in data]\n", + " y_list = y_list + [y for x,y,z in data]\n", + " speed = speed + [z for x,y,z in data]\n", + " return x_list, y_list, speed\n", + "x, y, speed = annoy(meta_data)\n", + "\n", + "average_speed = (st.mean(speed) * 60**2) / 1000\n", + "stan_dev = (st.stdev(speed) * 60**2) / 1000\n", + "s_limit = average_speed + stan_dev\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nJjeyB05gtQAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.xlabel(\"Time in Seconds\\n\\n Average Speed: {} Kilometers per hour\\n \\\n", + " Suggested Speed Limit: {} Kilometers per hour \".format(average_speed, s_limit))\n", + "plt.ylabel(\"Distance\")\n", + "plt.title(\"Traffic Flow on 1 km Road\")\n", + "colors = [np.random.choice([\"blue\", \"green\"]) for _ in x]\n", + "plt.scatter(y, x, s=1, c=colors, marker=\"|\")\n", + "\n", + "\n", + "\n", + "\n", + "plt.show() " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##Findings \n", + "#### By looking at my data I have come to the conclusion that a lower speed limit is generally better in normal mode on this road because otherwise the cars will group up too much trying to match the car in fronts speed." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.4.2" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/cars.py b/cars.py new file mode 100644 index 0000000..7cdaa8d --- /dev/null +++ b/cars.py @@ -0,0 +1,35 @@ +import random +from road import Road + +class Car: + + def __init__(self, start_position, length=5, max_speed=33, road=Road() ): + self.max_speed = max_speed # speed in m / s + self.speed = 0 # m / s + self.length = length # in meters + self.position = start_position + self.pre_pos = 0 + self.road = road + self.index_position = 0 + + def accelerate(self): + # accelerate 2 m/s + if self.speed < self.max_speed - 1: + self.speed += 2 + + def decelerate(self): + if self.speed > 2: + self.speed -= 2 + + def rand_slow(self): + # cars have a 10% chance of randomly slowing down by 2 m/s + if random.random() <= .1 and self.speed > 2: + self.decelerate() + + def move(self): + new_point = self.position + self.speed + self.pre_pos = self.position + if new_point <= self.road.length: + self.position = new_point + elif new_point >= self.road.length: + self.position = new_point - self.road.length diff --git a/requirements.txt b/requirements.txt index 8edbdf1..336b823 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,19 @@ -ipython[notebook] -matplotlib +gnureadline==6.3.3 +ipython==3.2.1 +Jinja2==2.7.3 +jsonschema==2.5.1 +MarkupSafe==0.23 +matplotlib==1.4.3 +mistune==0.7 +nose==1.3.7 +numpy==1.9.2 +ptyprocess==0.5 +Pygments==2.0.2 +pyparsing==2.0.3 +python-dateutil==2.4.2 +pytz==2015.4 +pyzmq==14.7.0 +six==1.9.0 +terminado==0.5 +tornado==4.2.1 +wheel==0.24.0 diff --git a/road.py b/road.py new file mode 100644 index 0000000..3a0f868 --- /dev/null +++ b/road.py @@ -0,0 +1,7 @@ +import numpy as np + +class Road: + # road is only one lane so there only needs to be a one dimensional array + def __init__(self, length=1000): + self.length = length # length in meters + self.road_state = np.zeros(self.length, int) \ No newline at end of file diff --git a/simulation.py b/simulation.py new file mode 100644 index 0000000..b5ba198 --- /dev/null +++ b/simulation.py @@ -0,0 +1,73 @@ +from road import Road +from cars import Car + +# cars take a position argument +# simulation takes a road argument + +class Sim: + + def __init__(self, road=Road(), cars_count=30): + self.cars_count = cars_count + self.road_state = road.road_state + self.cars_on_road = [] # contains all the cars on the road + self.time = 60 # time in seconds + self.tick = 1 + self.vehicle_data = [] + self.speed_data = [] + self.collisions = 0 + + def car_factory(self): + # * after initial code is finished come back here and design the simulation to + # * account for car length + init_location = 0 + my_location = 0 + for num in range(self.cars_count): + init_location = init_location + 33 + f_car = Car(init_location) # you need to pass in a position from road state + f_car.index_position = my_location + f_car.rand_slow() + self.cars_on_road.append(f_car) + my_location += 1 + + def update(self, vehicle): + # updates the current state of the road i.e.(changes the index position of cars from 0 to 1 + self.road_state[vehicle.pre_pos:vehicle.pre_pos + vehicle.speed] = 0 + self.road_state[vehicle.position:vehicle.position + vehicle.length] = 1 + self.min_distance_between_car(vehicle) + + def min_distance_between_car(self, object): + # location >= int(speed) in meters from car in front of it + # if another car is too close, car will match that cars speed + min_distance = object.speed + object.position + if not any(self.road_state[object.position:min_distance]) and object.speed < object.max_speed: + object.accelerate() + else: + if not any(self.road_state[object.position:min_distance]): + pass + elif object.index_position + 1 < self.cars_count: + new_speed = self.cars_on_road[object.index_position + 1].speed + object.speed = new_speed + elif object.index_position + 1 > self.cars_count: + new_speed = self.cars_on_road[1].speed + object.speed = new_speed + + + def traffic(self): + while self.time > 0: + #temp_data = [] + for vehicle in self.cars_on_road: + self.vehicle_data.append((self.tick, vehicle.position, vehicle.speed)) + self.min_distance_between_car(vehicle) + vehicle.rand_slow() + vehicle.move() + self.update(vehicle) + #self.vehicle_data.append(temp_data) + self.tick += 1 + self.time -= 1 + + def main(self): + self.car_factory() + self.traffic() + return self.vehicle_data + +