-
-
Notifications
You must be signed in to change notification settings - Fork 46.8k
add implementation of Nagel and Schrekenberg algo #5584
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
cclauss
merged 14 commits into
TheAlgorithms:master
from
Leoriem-code:cellular_automata
Oct 26, 2021
Merged
Changes from 8 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
58a7b9f
add implementation of Nagel and Schrekenberg algo
d5b724b
Merge branch 'TheAlgorithms:master' into cellular_automata
Leoriem-code df0c017
Update cellular_automata/nasch.py
Leoriem-code 2abdc96
Update nasch.py
Leoriem-code 7b05964
Merge branch 'TheAlgorithms:master' into cellular_automata
Leoriem-code 9921fdc
Update and rename nasch.py to nagel_schrekenberg.py
Leoriem-code 50905fa
Update cellular_automata/nagel_schrekenberg.py
Leoriem-code 4df9e0b
Update nagel_schrekenberg.py
Leoriem-code 926e87a
Update nagel_schrekenberg.py
Leoriem-code 842dde3
Update nagel_schrekenberg.py
Leoriem-code 0fe0715
update nagel_schrekenberg.py
7028c9c
Merge branch 'TheAlgorithms:master' into cellular_automata
Leoriem-code c1bb3d6
Merge branch 'TheAlgorithms:master' into cellular_automata
Leoriem-code a00fed8
Update nagel_schrekenberg.py
cclauss File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
from random import randint, random | ||
|
||
""" | ||
This algorithm simulate the evolution of a highway with only one road | ||
The highway is divided in cells, each cell can have at most one car in it | ||
The highway make a loop. That means that when a car comes to one end, they will | ||
come out of the other | ||
A car is represented by it's speed (from 0 to 5) | ||
|
||
Some information about speed: | ||
-1 means that the cell on the highway is empty | ||
0 to 5 are the speed of the cars with 0 being the lowest and 5 the highest | ||
|
||
More information here: https://en.wikipedia.org/wiki/Nagel%E2%80%93Schreckenberg_model | ||
|
||
Examples for doctest: | ||
>>> simulate(construct_highway(6, 3, 0), 2, 0, 2) | ||
[[0, -1, -1, 0, -1, -1], [-1, 1, -1, -1, 1, -1], [-1, -1, 1, -1, -1, 1]] | ||
>>> simulate(construct_highway(5, 2, -2), 3, 0, 2) | ||
[[0, -1, 0, -1, 0], [0, -1, 0, -1, -1], [0, -1, -1, 1, -1], [-1, 1, -1, 0, -1]] | ||
""" | ||
|
||
PROBABILITY = 0.1 # The probability that a driver will slow down | ||
SPEED_START = 1 # The speed of the cars a the start | ||
FREQUENCY = 5 # How many cells there are between two cars at the start | ||
MAX_SPEED = 5 # The maximum speed a car will go to | ||
NUMBER_OF_CELLS = 1024 # How many cell are there in the highway | ||
NUMBER_OF_UPDATE = 2048 # How many times will the position be updated | ||
highway = [] # Where every position and speed of every car will be stored | ||
|
||
|
||
def construct_highway( | ||
number_of_cells: int, | ||
FREQUENCY: int, | ||
SPEED_START: int, | ||
random_frequency: bool = False, | ||
random_speed: bool = False, | ||
MAX_SPEED: int = 5, | ||
) -> list: | ||
""" | ||
Build the highway following the parameters given | ||
>>> construct_highway(10, 2, 6) | ||
[[6, -1, 6, -1, 6, -1, 6, -1, 6, -1]] | ||
>>> construct_highway(10, 10, 2) | ||
[[2, -1, -1, -1, -1, -1, -1, -1, -1, -1]] | ||
""" | ||
|
||
highway = [[-1] * NUMBER_OF_CELLS] # Create a highway without any car | ||
i = 0 | ||
if SPEED_START < 0: | ||
SPEED_START = 0 | ||
while i < NUMBER_OF_CELLS: | ||
highway[0][i] = randint(0, MAX_SPEED) if random_speed else SPEED_START # Place the cars | ||
i = i + randint(1, MAX_SPEED * 2) if random_frequency else i + FREQUENCY # Arbitrary number, may need tuning | ||
return highway | ||
|
||
|
||
def get_distance(highway_now: list, car_index: int) -> int: | ||
""" | ||
Get the distance between a car (at index car_index) and the next car | ||
>>> get_distance([6,-1,6,-1,6], 2) | ||
1 | ||
>>> get_distance([2,-1,-1,-1,3,1,0,1,3,2], 0) | ||
3 | ||
>>> get_distance([-1,-1,-1,-1,2,-1,-1,-1,3], -1) | ||
4 | ||
""" | ||
|
||
distance = 0 | ||
cells = highway_now[car_index + 1 :] | ||
for cell in range(len(cells)): # May need a better name for this | ||
if cells[cell] != -1: # If the cell is not empty then | ||
return distance # we have the distance we wanted | ||
else: | ||
Leoriem-code marked this conversation as resolved.
Show resolved
Hide resolved
|
||
distance += 1 | ||
Leoriem-code marked this conversation as resolved.
Show resolved
Hide resolved
|
||
# Here if the car is near the end of the highway | ||
return distance + get_distance(highway_now, -1) | ||
|
||
|
||
def update(highway_now: list, PROBABILITY: float, MAX_SPEED: int) -> list: | ||
""" | ||
Update the speed of the cars | ||
>>> update([-1,-1,-1,-1,-1,2,-1,-1,-1,-1,3], 0.0, 5) | ||
[-1, -1, -1, -1, -1, 3, -1, -1, -1, -1, 4] | ||
>>> update([-1,-1,2,-1,-1,-1,-1,3], 0.0, 5) | ||
[-1, -1, 3, -1, -1, -1, -1, 1] | ||
""" | ||
|
||
NUMBER_OF_CELLS = len(highway_now) | ||
# Beforce calculations, the highway is empty | ||
next_highway = [-1] * NUMBER_OF_CELLS | ||
|
||
for car_index in range(NUMBER_OF_CELLS): | ||
if highway_now[car_index] != -1: | ||
# Add 1 to the current speed of the car and cap the speed | ||
next_highway[car_index] = min(highway_now[car_index] + 1, MAX_SPEED) | ||
# Number of empty cell before the next car | ||
dn = get_distance(highway_now, car_index) - 1 | ||
# We can't have the car causing an accident | ||
next_highway[car_index] = min(next_highway[car_index], dn) | ||
if random() < PROBABILITY: | ||
# Randomly, a driver will slow down | ||
next_highway[car_index] = max(next_highway[car_index] - 1, 0) | ||
return next_highway | ||
|
||
|
||
def simulate( | ||
highway: list, NUMBER_OF_UPDATE: int, PROBABILITY: float, MAX_SPEED: int | ||
) -> list: | ||
""" | ||
The main function, it will simulate the evolution of the highway | ||
>>> simulate([[-1,2,-1,-1,-1,3]], 2, 0.0, 3) | ||
[[-1, 2, -1, -1, -1, 3], [-1, -1, -1, 2, -1, 0], [1, -1, -1, 0, -1, -1]] | ||
>>> simulate([[-1,2,-1,3]], 4, 0.0, 3) | ||
[[-1, 2, -1, 3], [-1, 0, -1, 0], [-1, 0, -1, 0], [-1, 0, -1, 0], [-1, 0, -1, 0]] | ||
""" | ||
|
||
NUMBER_OF_CELLS = len(highway[0]) | ||
|
||
for i in range(NUMBER_OF_UPDATE): | ||
next_speeds_calculated = update(highway[i], PROBABILITY, MAX_SPEED) | ||
real_next_speeds = [-1] * NUMBER_OF_CELLS | ||
|
||
for car_index in range(NUMBER_OF_CELLS): | ||
speed = next_speeds_calculated[car_index] | ||
if speed != -1: | ||
# Change the position based on the speed (with % to create the loop) | ||
index = (car_index + speed) % NUMBER_OF_CELLS | ||
# Commit the change of position | ||
real_next_speeds[index] = speed | ||
highway.append(real_next_speeds) | ||
|
||
return highway | ||
|
||
|
||
if __name__ == "__main__": | ||
import doctest | ||
|
||
doctest.testmod() |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.