import numpy as np
import scipy as sp
import random
'''
Inputs of the class:
road length, traffic density, maximum velocity,
the probability of slowing down, the probability of changing lanes
'''
class TrafficSimulation_2lane:
def __init__(self, road_length = 100, density = 0.2, max_velocity = 5, slow_prob = 0.3, lane_prob = 0.8):
self.road_length = road_length
self.density = density
self.max_velocity = max_velocity
self.slow_prob = slow_prob
self.lane_prob = lane_prob
self.flow_count = 0
self.state1 = -sp.ones(100, dtype=int)
self.state2 = -sp.ones(100, dtype=int)
for i in range(200):
if random.random() <= self.density:
if i<100:
self.state1[i] = random.randint(0,5)
else:
self.state2[i-100] = random.randint(0,5)
def update(self):
m = self.max_velocity
next_state1 = -sp.ones(100, dtype=int)
next_state2 = -sp.ones(100, dtype=int)
current_index1 = np.argwhere(self.state1!=-1)
current_index2 = np.argwhere(self.state2!=-1)
update_index1 = current_index1
update_index2 = current_index2
'''Determine if cars on lane #1 will change lanes '''
for i in range(len(current_index1)):
c = current_index1[i]
n1 = current_index1[(i+1) % len(current_index1)]
v = self.state1[c]
if (n1-c)%100-1 >= v + 1:
break
if self.state2[c] >= 0 or (n1-c)%100 > v:
break
for dx in range(1, m):
if self.state2[(c - dx)%100] >= 0:
loback = False
else:
loback = True
for dx in range(1, m):
if self.state2[(c + dx)%100] >= 0:
lo = dx - 1
break
else:
lo = m - 1
if loback == True and lo >= v and random.random()<= self.lane_prob:
c_index = np.argwhere(update_index1 == c)
new_index1 = np.delete(update_index1, c_index)
update_index1 = new_index1
update_index2 = update_index2.flatten()
insertindex = np.searchsorted(update_index2, c[0])
update_index2 = np.insert(update_index2, insertindex, c)
'''Determine if cars on lane 2 will change lanes '''
for i in range(len(current_index2)):
c = current_index2[i]
n2 = current_index2[(i+1) % len(current_index2)]
v = self.state2[c]
if (n2-c)%100 >= v + 1:
break
if self.state1[c] >= 0:
break
for dx in range(1, m):
if self.state1[(c - dx)%100] >= 0:
loback = False
else:
loback = True
for dx in range(1, m):
if self.state1[(c + dx)%100] >= 0:
lo = dx - 1
break
else:
lo = m - 1
if loback == True and lo >= v and random.random()<= self.lane_prob:
c_index = np.argwhere(update_index2 == c)
new_index2 = np.delete(update_index2, c_index)
update_index2 = new_index2
update_index1 = update_index1.flatten()
insertindex = np.searchsorted(update_index1, c[0])
update_index1 = np.insert(update_index1, insertindex, c)
'''update the car movements on both lane'''
for i in range(len(update_index1)):
c = update_index1[i]
n = update_index1[(i+1) % len(update_index1)]
v = self.state1[c]
if v < m and (n-c)%100 > v:
v = v + 1
if v > 0 and (n-c)%100 <= v :
v = (n-c)%100 -1
if v > 0 and random.random() <= self.slow_prob:
v = v-1
next_state1[(c + v) % 100] = v
if c + v >= 100:
self.flow_count += 1
for i in range(len(update_index2)):
c = update_index2[i]
n = update_index2[(i+1) % len(update_index2)]
v = self.state2[c]
if v < m and (n-c)%100 > v:
v = v + 1
if v > 0 and (n-c)%100 <= v :
v = (n-c)%100 - 1
if v > 0 and random.random() <= self.slow_prob:
v = v - 1
next_state2[(c + v) % 100] = v
if c + v >= 100:
self.flow_count += 1
self.state1 = next_state1
self.state2 = next_state2
def display(self):
print(''.join('.' if x == -1 else str(x) for x in self.state1)),"____",
print(''.join('.' if x == -1 else str(x) for x in self.state2))
print