Traffic simulation using Simpy

huangapple go评论84阅读模式
英文:

Traffic simulation using Simpy

问题

我已经使用代码翻译了您提供的文本,以下是翻译好的部分:

  1. 我一直在使用Simpy来设计一个信号控制的交叉口的交通模拟(三个进口道)。附加的代码描述了汽车在单车道道路上行驶并仅从一个方向到达交叉口的设计。交通信号在绿灯和红灯之间切换。我的问题是:如何修改代码以模拟多个具有不同到达率的交通信号,这些信号按顺序在同一个交叉口工作。我的目标是将多个道路连接到交叉口,并通过交通信号控制交通流动。
  2. 提前致谢。
  3. # 然后是代码的部分...

请注意,代码部分未进行翻译。如果您需要进一步的帮助或有其他问题,请随时提出。

英文:

I have been working on simpy to design a traffic simulation of a signalized intersection (three approaches). The attached code described the design of the cars driving on a single lane road and arrive at the intersection from one direction only. The traffic light switching between green and red intervals. my question is: how to modify the code to simulate more than one traffic signal with different arrival rate that work in sequence at the same intersection. My goal is to connect more than one road to the intersection and control the traffic movement by a traffic signal.

Thanks in advance.

  1. # Section 1: Import from modules and define a utility class.
  2. from collections import deque # double-ended queue
  3. from numpy import random
  4. import simpy
  5. from simpy.util import start_delayed
  6. class Struct(object):
  7. """
  8. This simple class allows one to create an object whose attributes are
  9. initialized via keyword argument/value pairs. One can update the attributes
  10. as needed later.
  11. """
  12. def __init__(self, **kwargs):
  13. self.__dict__.update(kwargs)
  14. # Section 2: Initializations.
  15. random.seed([1, 2, 3])
  16. # Total number of seconds to be simulated:
  17. end_time= 200.0
  18. # Cars cars arrive at the traffic light according to a Poisson process with an
  19. # average rate of 0.2 per second:
  20. arrival_rate= 0.2
  21. t_interarrival_mean= 1.0 / arrival_rate
  22. # Traffic light green and red durations:
  23. t_green= 30.0; t_red= 40.0
  24. # The time for a car at the head of the queue to depart (clear the intersection)
  25. # is modeled as a triangular distribution with specified minimum, maximum, and
  26. # mode.
  27. t_depart_left= 1.6; t_depart_mode= 2.0; t_depart_right= 2.4
  28. # Initially, no cars are waiting at the light:
  29. queue= deque()
  30. # Track number of cars:
  31. arrival_count= departure_count= 0
  32. Q_stats= Struct(count=0, cars_waiting=0)
  33. W_stats= Struct(count=0, waiting_time=0.0)
  34. # Section 3: Arrival event.
  35. def arrival():
  36. """
  37. This generator functions simulates the arrival of a car. Cars arrive
  38. according to a Poisson process having rate `arrival_rate`. The times between
  39. subsequent arrivals are i.i.d. exponential random variables with mean
  40. t_interarrival_mean= 1.0 / arrival_rate
  41. """
  42. global arrival_count, env, light, queue
  43. while True:
  44. arrival_count+= 1
  45. if light == 'red' or len(queue):
  46. # The light is red or there is a queue of cars. ==> The new car joins
  47. # the queue. Append a tuple that contains the number of the car and
  48. # the time at which it arrived:
  49. queue.append((arrival_count, env.now))
  50. print("Car #%d arrived and joined the queue at position %d at time "
  51. "%.3f." % (arrival_count, len(queue), env.now))
  52. else:
  53. # The light is green and no cars are waiting. ==> The new car passes
  54. # through the intersection immediately.
  55. print("Car #%d arrived to a green light with no cars waiting at time "
  56. "%.3f." % (arrival_count, env.now))
  57. # Record waiting time statistics. (This car experienced zero waiting
  58. # time, so we increment the count of cars, but the cumulative waiting
  59. # time remains unchanged.
  60. W_stats.count+= 1
  61. # Schedule next arrival:
  62. yield env.timeout( random.exponential(t_interarrival_mean))
  63. # Section 4: Define event functions.
  64. # Section 4.1: Departure event.
  65. def departure():
  66. """
  67. This generator function simulates the 'departure' of a car, i.e., a car that
  68. previously entered the intersection clears the intersection. Once a car has
  69. departed, we remove it from the queue, and we no longer track it in the
  70. simulation.
  71. """
  72. global env, queue
  73. while True:
  74. # The car that entered the intersection clears the intersection:
  75. car_number, t_arrival= queue.popleft()
  76. print("Car #%d departed at time %.3f, leaving %d cars in the queue."
  77. % (car_number, env.now, len(queue)))
  78. # Record waiting time statistics:
  79. W_stats.count+= 1
  80. W_stats.waiting_time+= env.now - t_arrival
  81. # If the light is red or the queue is empty, do not schedule the next
  82. # departure. `departure` is a generator, so the `return` statement
  83. # terminates the iterator that the generator produces.
  84. if light == 'red' or len(queue) == 0:
  85. return
  86. # Generate departure delay as a random draw from triangular distribution:
  87. delay= random.triangular(left=t_depart_left, mode=t_depart_mode,
  88. right=t_depart_right)
  89. # Schedule next departure:
  90. yield env.timeout(delay)
  91. # Section 4.2: Light change-of-state event.
  92. def light():
  93. """
  94. This generator function simulates state changes of the traffic light. For
  95. simplicity, the light is either green or red--there is no yellow state.
  96. """
  97. global env, light
  98. while True:
  99. # Section 4.2.1: Change the light to green.
  100. light= 'green'
  101. print("\nThe light turned green at time %.3f." % env.now)
  102. # If there are cars in the queue, schedule a departure event:
  103. if len(queue):
  104. # Generate departure delay as a random draw from triangular
  105. # distribution:
  106. delay= random.triangular(left=t_depart_left, mode=t_depart_mode,
  107. right=t_depart_right)
  108. start_delayed(env, departure(), delay=delay)
  109. # Schedule event that will turn the light red:
  110. yield env.timeout(t_green)
  111. # Section 4.2.2: Change the light to red.
  112. light= 'red'
  113. print("\nThe light turned red at time %.3f." % env.now)
  114. # Schedule event that will turn the light green:
  115. yield env.timeout(t_red)
  116. # Section 4.3: Schedule event that collects Q_stats.
  117. def monitor():
  118. """
  119. This generator function produces an interator that collects statistics on the
  120. state of the queue at regular intervals. An alternative approach would be to
  121. apply the PASTA property of the Poisson process ('Poisson Arrivals See Time
  122. Averages') and sample the queue at instants immediately prior to arrivals.
  123. """
  124. global env, Q_stats
  125. while True:
  126. Q_stats.count+= 1
  127. Q_stats.cars_waiting+= len(queue)
  128. yield env.timeout(1.0)
  129. # Section 5: Schedule initial events and run the simulation. Note: The first
  130. # change of the traffic light, first arrival of a car, and first statistical
  131. # monitoring event are scheduled by invoking `env.process`. Subsequent changes
  132. # will be scheduled by invoking the `timeout` method. With this scheme, there
  133. # is only one event of each of these types scheduled at any time; this keeps the
  134. # event queue short, which is good for both memory utilization and running time.
  135. print("\nSimulation of Cars Arriving at Intersection Controlled by a Traffic "
  136. "Light\n\n")
  137. # Initialize environment:
  138. env= simpy.Environment()
  139. # Schedule first change of the traffic light:
  140. env.process(light())
  141. # Schedule first arrival of a car:
  142. t_first_arrival= random.exponential(t_interarrival_mean)
  143. start_delayed(env, arrival(), delay=t_first_arrival)
  144. # Schedule first statistical monitoring event:
  145. env.process(monitor())
  146. # Let the simulation run for specified time:
  147. env.run(until=end_time)
  148. # Section 6: Report statistics.
  149. print("\n\n *** Statistics ***\n\n")
  150. print("Mean number of cars waiting: %.3f"
  151. % (Q_stats.cars_waiting / float(Q_stats.count)))
  152. print("Mean waiting time (seconds): %.3f"
  153. % (W_stats.waiting_time / float(W_stats.count)))

答案1

得分: 0

以下是您要翻译的代码部分:

  1. You need a master light controller to manage all your lights. I used the subscribe / publish pattern where each lane subscribed to the light they are interested in with a callback function. the light uses these callback functions to publish when the light is on. I treat red and green light as separate lights. The master light controller rotates through all the lights, calling each light's subscribers' callback function when the light turns on.
  2. This models a cross road, If you want to model a tee, just comment out any one lane.
  3. """
  4. Simulation of a traffic intersection
  5. Has four main lanes of traffic: North, South, East, and West
  6. for each direction there is also a turn lane: North left.... ect
  7. Assumes opposing lanes (such as North, and South)
  8. will have the same light color
  9. Light are manganed by a light controler
  10. Lanes "subscribe" to the light color they are interested in
  11. with a callback function
  12. When the light color comes on, the light control calls the callback
  13. function of the lanes that subscribed to that light color
  14. When a lane has a green light, it sends cars through the intersection,
  15. otherwise arriving cars accumulate in a queue
  16. Programmer: Michael R. Gibbs
  17. """
  18. import simpy
  19. import random
  20. class LightControl():
  21. """
  22. Controls the color and timing of the lights
  23. """
  24. def __init__(self, env):
  25. self.env = env
  26. # subscrition lists for each color and direction combo
  27. self.red_ns_subs = []
  28. self.red_ns_left_subs = []
  29. self.red_ew_subs = []
  30. self.red_ew_left_subs = []
  31. self.green_ns_subs = []
  32. self.green_ns_left_subs = []
  33. self green_ew_subs = []
  34. self green_ew_left_subs = []
  35. # start the lights
  36. self.env.process(self.run_lights())
  37. def _braodcast(self, subscribers):
  38. """
  39. utility to call the callback funcs for each subscriber
  40. """
  41. for callback in subscribers:
  42. callback()
  43. def run_lights(self):
  44. """
  45. controls the lights with a simple loop
  46. note different light have different times
  47. """
  48. while True:
  49. print(f'{self.env.now} ns left is green')
  50. self._braodcast(self.green_ns_left_subs)
  51. yield self.env.timeout(60)
  52. self._braodcast(self.red_ns_left_subs)
  53. self._braodcast(self.green_ns_subs)
  54. print(f'{self.env.now} ns is green')
  55. yield self.env.timeout(180)
  56. self._braodcast(self.red_ns_subs)
  57. self._braodcast(self.green_ew_left_subs)
  58. print(f'{self.env.now} ew left is green')
  59. yield self.env.timeout(60)
  60. self._braodcast(self.red_ew_left_subs)
  61. self._braodcast(self.green_ew_subs)
  62. print(f'{self.env.now} ew is green')
  63. yield self.env.timeout(120)
  64. self._braodcast(self.red_ew_subs)
  65. class Lane():
  66. """
  67. lane of traffic
  68. accumulates cars,
  69. waits for green light,
  70. sends cars through interscetion, until red light
  71. note if a car is already in the intersection when
  72. the light truns red, it will finish its trip and
  73. continue through
  74. """
  75. def __init__(self, name, env):
  76. self.name = name
  77. self.env = env
  78. self.lane_q = []
  79. self.green = False
  80. def add_car(self, car):
  81. """
  82. car arrives at lane
  83. """
  84. self.lane_q.append(car)
  85. def move_cars(self):
  86. """
  87. move cars through the intersection until light turns red
  88. """
  89. while self.green and (len(self.lane_q) > 0):
  90. car = self.lane_q.pop(0)
  91. yield self.env.timeout(10)
  92. print(f'{self.env.now} {self.name} sent car through')
  93. def green_light(self):
  94. """
  95. callback telling the lane that the light is green,
  96. starts moving cars through the intersection
  97. """
  98. self.green = True
  99. self.env.process(self.move_cars())
  100. def red_light(self):
  101. """
  102. callback telling the lane the light is red
  103. sets stop flag
  104. """
  105. self.green = False
  106. def gen_cars(env, lane, delay_func):
  107. """
  108. generates cars arriving at a lane
  109. """
  110. while True:
  111. yield env.timeout(delay_func())
  112. lane.add_car(object())
  113. # init sim
  114. env = simpy.Environment()
  115. lights = LightControl(env)
  116. # make lanes and subscibe to a lights with a callback
  117. north =Lane('North lane', env)
  118. lights.green_ns_subs.append(north.green_light)
  119. lights.red_ns_subs.append(north.red_light)
  120. north_left =Lane('North left lane', env)
  121. lights.green_ns_left_subs.append(north_left.green_light)
  122. lights.red_ns_left_subs.append(north_left.red_light)
  123. south =Lane('South lane', env)
  124. lights.green_ns_subs.append(south.green_light)
  125. lights.red_ns_subs.append(south.red_light)
  126. south_left =Lane('South left lane', env)
  127. lights.green_ns_left_subs.append(south_left.green_light)
  128. lights.red_ns_left_subs.append(south_left.red_light)
  129. east =Lane('East lane', env)
  130. lights.green_ew_subs.append(east.green_light)
  131. lights.red_ew_subs.append(east.red_light)
  132. east_left =Lane('East left lane', env)
  133. lights.green_ew_left_subs.append(east_left.green_light)
  134. lights.red_ew_left_subs.append(east_left.red_light)
  135. west =Lane('West lane', env)
  136. lights.green_ew_subs.append(west.green_light)
  137. lights.red_ew_subs.append(west.red_light)
  138. west_left =Lane('West left lane', env)
  139. lights.green_ew_left_subs.append(west_left.green_light)
  140. lights.red_ew_left_subs.append(west_left.red_light)
  141. # generate cars for each lane
  142. env.process(gen_cars(env, north, lambda : random.triangular(5,15,10)))
  143. env.process(gen_cars(env, north_left, lambda : random.triangular(10,30,20)))
  144. env.process(gen_cars(env, south, lambda : random.triangular(5,15,10)))
  145. env.process(gen_cars(env, south_left, lambda : random.triangular(12,35,20)))
  146. env.process(gen_cars(env, east, lambda : random.triangular(10,40,30)))
  147. env.process(gen_cars(env, east_left, lambda : random.triangular(15,45,30)))
  148. env.process(gen_cars(env, west, lambda : random.triangular(11,45,35)))
  149. env.process(gen_cars(env, west_left, lambda : random.triangular(15,50
  150. <details>
  151. <summary>英文:</summary>
  152. You need a master light controller to manage all your lights. I used the subscribe / publish pattern where each lane subscribed to the light they are interested in with a callback function. the light uses these callback functions to publish when the light is on. I treat red and green light as separate lights. The master light controller rotates through all the lights, calling each light&#39;s subscribers&#39; callback function when the light turns on.
  153. This models a cross road, If you want to model a tee, just comment out any one lane.
  154. &quot;&quot;&quot;
  155. Simulation of a traffic intersection
  156. Has four main lanes of traffic: North, South, East, and West
  157. for each direction there is also a turn lane: North left.... ect
  158. Assumes opposing lanes (such as North, and South)
  159. will have the same light color
  160. Light are manganed by a light controler
  161. Lanes &quot;subscribe&quot; to the light color they are interested in
  162. with a callback function
  163. When the light color comes on, the light control calls the callback
  164. function of the lanes that subscribed to that light color
  165. When a lane has a green light, it sends cars through the intersection,
  166. otherwise arriving cars accumulate in a queue
  167. Programmer: Michael R. Gibbs
  168. &quot;&quot;&quot;
  169. import simpy
  170. import random
  171. class LightControl():
  172. &quot;&quot;&quot;
  173. Controls the color and timing of the lights
  174. &quot;&quot;&quot;
  175. def __init__(self, env):
  176. self.env = env
  177. # subscrition lists for each color and direction combo
  178. self.red_ns_subs = []
  179. self.red_ns_left_subs = []
  180. self.red_ew_subs = []
  181. self.red_ew_left_subs = []
  182. self.green_ns_subs = []
  183. self.green_ns_left_subs = []
  184. self.green_ew_subs = []
  185. self.green_ew_left_subs = []
  186. # start the lights
  187. self.env.process(self.run_lights())
  188. def _braodcast(self, subscribers):
  189. &quot;&quot;&quot;
  190. utility to call the callback funcs for each subscriber
  191. &quot;&quot;&quot;
  192. for callback in subscribers:
  193. callback()
  194. def run_lights(self):
  195. &quot;&quot;&quot;
  196. controls the lights with a simple loop
  197. note different light have different times
  198. &quot;&quot;&quot;
  199. while True:
  200. print(f&#39;{self.env.now} ns left is green&#39;)
  201. self._braodcast(self.green_ns_left_subs)
  202. yield self.env.timeout(60)
  203. self._braodcast(self.red_ns_left_subs)
  204. self._braodcast(self.green_ns_subs)
  205. print(f&#39;{self.env.now} ns is green&#39;)
  206. yield self.env.timeout(180)
  207. self._braodcast(self.red_ns_subs)
  208. self._braodcast(self.green_ew_left_subs)
  209. print(f&#39;{self.env.now} ew left is green&#39;)
  210. yield self.env.timeout(60)
  211. self._braodcast(self.red_ew_left_subs)
  212. self._braodcast(self.green_ew_subs)
  213. print(f&#39;{self.env.now} ew is green&#39;)
  214. yield self.env.timeout(120)
  215. self._braodcast(self.red_ew_subs)
  216. class Lane():
  217. &quot;&quot;&quot;
  218. lane of traffic
  219. accumulates cars,
  220. waits for green light,
  221. sends cars through interscetion, until red light
  222. note if a car is already in the intersection when
  223. the light truns red, it will finish its trip and
  224. continue through
  225. &quot;&quot;&quot;
  226. def __init__(self, name, env):
  227. self.name = name
  228. self.env = env
  229. self.lane_q = []
  230. self.green = False
  231. def add_car(self, car):
  232. &quot;&quot;&quot;
  233. car arrives at lane
  234. &quot;&quot;&quot;
  235. self.lane_q.append(car)
  236. def move_cars(self):
  237. &quot;&quot;&quot;
  238. move cars through the intersection until light turns red
  239. &quot;&quot;&quot;
  240. while self.green and (len(self.lane_q) &gt; 0):
  241. car = self.lane_q.pop(0)
  242. yield self.env.timeout(10)
  243. print(f&#39;{self.env.now} {self.name} sent car through&#39;)
  244. def green_light(self):
  245. &quot;&quot;&quot;
  246. callback telling the lane that the light is green,
  247. starts moving cars through the intersection
  248. &quot;&quot;&quot;
  249. self.green = True
  250. self.env.process(self.move_cars())
  251. def red_light(self):
  252. &quot;&quot;&quot;
  253. callback telling the lane the light is red
  254. sets stop flag
  255. &quot;&quot;&quot;
  256. self.green = False
  257. def gen_cars(env, lane, delay_func):
  258. &quot;&quot;&quot;
  259. generates cars arriving at a lane
  260. &quot;&quot;&quot;
  261. while True:
  262. yield env.timeout(delay_func())
  263. lane.add_car(object())
  264. # init sim
  265. env = simpy.Environment()
  266. lights = LightControl(env)
  267. # make lanes and subscibe to a lights with a callback
  268. north =Lane(&#39;North lane&#39;, env)
  269. lights.green_ns_subs.append(north.green_light)
  270. lights.red_ns_subs.append(north.red_light)
  271. north_left =Lane(&#39;North left lane&#39;, env)
  272. lights.green_ns_left_subs.append(north_left.green_light)
  273. lights.red_ns_left_subs.append(north_left.red_light)
  274. south =Lane(&#39;South lane&#39;, env)
  275. lights.green_ns_subs.append(south.green_light)
  276. lights.red_ns_subs.append(south.red_light)
  277. south_left =Lane(&#39;South left lane&#39;, env)
  278. lights.green_ns_left_subs.append(south_left.green_light)
  279. lights.red_ns_left_subs.append(south_left.red_light)
  280. east =Lane(&#39;East lane&#39;, env)
  281. lights.green_ew_subs.append(east.green_light)
  282. lights.red_ew_subs.append(east.red_light)
  283. east_left =Lane(&#39;East left lane&#39;, env)
  284. lights.green_ew_left_subs.append(east_left.green_light)
  285. lights.red_ew_left_subs.append(east_left.red_light)
  286. west =Lane(&#39;West lane&#39;, env)
  287. lights.green_ew_subs.append(west.green_light)
  288. lights.red_ew_subs.append(west.red_light)
  289. west_left =Lane(&#39;West left lane&#39;, env)
  290. lights.green_ew_left_subs.append(west_left.green_light)
  291. lights.red_ew_left_subs.append(west_left.red_light)
  292. # generate cars for each lane
  293. env.process(gen_cars(env, north, lambda : random.triangular(5,15,10)))
  294. env.process(gen_cars(env, north_left, lambda : random.triangular(10,30,20)))
  295. env.process(gen_cars(env, south, lambda : random.triangular(5,15,10)))
  296. env.process(gen_cars(env, south_left, lambda : random.triangular(12,35,20)))
  297. env.process(gen_cars(env, east, lambda : random.triangular(10,40,30)))
  298. env.process(gen_cars(env, east_left, lambda : random.triangular(15,45,30)))
  299. env.process(gen_cars(env, west, lambda : random.triangular(11,45,35)))
  300. env.process(gen_cars(env, west_left, lambda : random.triangular(15,50,40)))
  301. env.run(1200)
  302. </details>

huangapple
  • 本文由 发表于 2023年2月18日 01:07:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75487283.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定