本文主要是介绍基于Netlogo的高速道路“幽灵堵车”模型研究,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一、实验目的
在现实生活中,高速公路上的交通拥堵是一个常见而头疼的问题。今年春节假期间,我们一家人从江苏苏州驱车前往安徽合肥的老家。作为全国高速交通的重要枢纽,安徽段高速也迎来了一年一度的春运堵车高峰。为了避免路上堵车耽误行程,我们特地选择凌晨车流较少时出发,但仍然遇到了4段比较严重的堵车,但是这几次堵车体验下来,只有1次是车辆追尾事故导致的堵车,其他的均为不明原因导致的无事故堵车,交通领域的专家们将这一现象称为“幽灵堵车”。
理解和模拟高速道路中“幽灵堵车”现象对于交通管理和规划至关重要。本课程作业旨在利用群体智能的方法,通过NetLogo软件模拟高速道路上的交通流动情况,分析高速路上不同车辆之间车道、车速以及变道策略对于道路通畅程度的影响,以便更好地理解和研究堵车现象的产生机制及应对策略。
二、实验内容
1、高速堵车问题建模
为了尽可能真实的模拟高速实际行驶与堵车产生情况,我结合自己的驾驶经验,总结出几条高速道路行驶过程中的几条规则:
1.1道路环境
1)高速公路具有多条车道,通过查阅资料可知,我国车道一般均为单向2-4个车道;
2)在正常行驶、无匝道口等其他情况时,相邻两个车道之间可以允许相互变道。
1.2车辆行为
1)车辆在车道上保持单向行驶,不可以逆行;
2)行驶时具备可以测量和控制的速度,且不能大于设定的最高速度,也不能小于实际的最低速度0;
3)车辆具有最大的加速度和最大的减速度,会根据前车的位置完成加速和减速;
4)当正常行驶的车辆遇到同车道的相对慢速的前车时,车辆会执行减速以确保不会相撞,但当等待前方慢车的时间过长,后方车辆则会选择变更至相邻车道完成超车;
5)根据交通规则,车辆只能在相邻两条车道之间进行变道,即使车道数足够,也不可以进行跨车道的变道操作。
2、Netlogo实现
根据前文中针对实际高速公路行驶场景的规则分析,可以结合前面的几点规则完成Netlogo的仿真实现,对前文提到的几点规则结合实际情况做出如下的简化与改进设计:
2.1道路环境
1)程序仅研究正常直线行驶路段现象的形成原因,并分析影响因素,暂不考虑匝道汇入、违规变道、交通事故道路变窄等比较显著的外界影响因素。
2)仿真程序中车道取2-4之间的固定值,也可以比较不同车道数对于高速堵车现象的影响。
2.2车辆行为
1)在车辆的属性定义上,每辆车设定有实际行驶速度、最大行驶速度、目标车道和变道耐心值等属性,同时具有加速、减速、变道的行为,每种行为均为Netlogo程序中的一个子程序,当行驶达成某种条件时便会进行调用以实现功能。
2)单独说明下最后一个与前文有些变动的变道耐心值属性,这是用于控制车辆是否选择变道的变量,其功能为:对于设定的耐心值,初始时正常行驶的所有车辆均设定为最高耐心值,而当车辆由于前方的拥堵导致的减速时,没经历一个仿真时刻的减速就会将耐心值减1,当耐心值归零时,车辆就会随机选择相邻的车道进行变道,并更新耐心值为最大值。
3)仿真道路中车辆均保持单向行驶,初速度设定为某一设定速度±15%范围内的随机值,且车道分布随机,以模拟实际高速道路行车的实际情况。
程序的总体原理框图如图 1所示:
图 1 程序原理框图
下面我结合实际几个典型的程序进行功能说明。
globals [selected-car ; 当前选择的汽车lanes ; 不同车道的y坐标列表
]turtles-own [speed ; 当前速度top-speed ; 最大速度target-lane ; 目标车道patience ; 驾驶员耐心值
]
这段代码定义了程序中使用的全局变量,类似与c语言中结构体的概念。其中globals中为定义汽车的相关变量, selected-car用于指定当前选择的汽车,而 lanes则是一个列表,包含了不同车道的y坐标,即车道的序号。这些全局变量在整个程序的循环中都可以被随时访问和更新。
后面的turtles-own则是定义了每辆汽车拥有的属性,speed 表示汽车当前的速度,top-speed 表示汽车的最大速度(每辆车不同),target-lane 表示汽车的目标车道,patience 表示驾驶员的耐心值。这些属性在程序中用于控制汽车的行为和状态。
to setupclear-allset-default-shape turtles "car"draw-roadcreate-or-remove-carsreset-ticks
end
这段代码定义了Netlogo程序的初始化setup函数,用于初始化程序运行的相关功能。在函数中,首先清空模拟环境,然后设置所有车辆的形状为内置的 "car"指定的形状,调用绘制道路、创建或删除车辆、以及随机选择一辆汽车并将其标记为红色指定车辆的子函数。最后,重置模拟的循环次数tick值。
to create-or-remove-cars;删除大于设置数量的车辆let road-patches patches with [ member? pycor lanes ]if number-of-cars > count road-patches [set number-of-cars count road-patches]create-turtles (number-of-cars - count turtles) [;设置汽车的颜色为指定的蓝色域附近的颜色set color car-color;假设有一个 free road-patches 的集合,在下面的函数中进行判断其中包含了所有空闲的道路地块。;通过 one-of 函数,从这个集合中随机选择一个地块,并使用 move-to 命令让当前的乌龟移动到该地块上。move-to one-of free road-patchesset target-lane pycorset heading 90set top-speed 0.5 + random-float 0.5set speed 0.5set patience random max-patience];判断当前车辆的数量是否大于设定的number of cars如果大于则删除超过数量的turtlesif count turtles > number-of-cars [let n count turtles - number-of-carsask n-of n [ other turtles ] of selected-car [ die ]]
end
这段代码定义了创建或删除车辆的函数。其功能为根据当前道路的空闲区域,确保道路上不会超过一定数量的车辆。另外程序也可以实现创建新的车辆,设置其颜色、位置、目标车道、速度、最大速度和耐心值。如果现有车辆数超过指定数量,则删除多余的车辆。
to draw-roadask patches [set pcolor green - random-float 0.5]set lanes n-values number-of-lanes [ n -> number-of-lanes - (n * 2) - 1 ]ask patches with [ abs pycor <= number-of-lanes ] [set pcolor grey - 2.5 + random-float 0.25]draw-road-lines
end
这段代码定义了绘制道路的函数。对于程序中的每个patches,可以设置区域的颜色为绿色,并让颜色在绿色色域附近取适当变动值,以使整体的绿色形成的“草地”看起来更加自然,后面车道的设置也同理。最后,调用 draw-road-lines 函数绘制道路上的标线,绘制出如图 2所示的地图。
图 2 函数生成的地图以及模型的UI界面
;驱动函数
to gorepeat 100 [create-or-remove-carsask turtles [ move-forward ]ask turtles with [ patience <= 0 ] [ choose-new-lane ]ask turtles with [ ycor != target-lane ] [ move-to-target-lane ]tick]
end
这段代码为程序的主要运行逻辑,类似于c语言的main函数,在程序完成了setup初始化后,通过go函数调用了前面提到的其他的子函数,实现整体模型的仿真。
三、实验结果与分析
结合前面的分析说明,我在程序中共设计了四个方便直接通过滑块调节的变量,具体如图 2所示。此外,为了减少不相关变量之间的相互影响,便于统一对比仿真结果,我将仿真总步数定为10000步,初始车辆数为40,初始车道数为2,程序采用归一化的速度值,即速度取值范围为0~1之间,设置初始速度为0.5,并通过“set top-speed 0.5 + random-float 0.5”设置所有车辆的最大速度为0.5~1之间的随机值,通过Netlogo软件自带的高出绘图数据的功能,将模型运行后的数据导出到Origin Pro中,进行数据处理并绘制数据图表。
图 3 可调节变量
结合实际生活,过年的时候我清楚的记得,当高速从江苏界进入了安徽界之后,最大的变化就是车道的变窄,从原先宽敞的四车道变成了局促的双车道,车流也就是在这个时候变得更加拥挤。
因此基于这个模型,我首先想到的就是车道数量变化对于车辆行驶影响,并进行模型的相关数据对比。通过改变number-of-lanes,可以得到如图 5~4所示的三组数据。
1、车道数量对于车速的影响
如图 3所示为三种不同车道数量下,所有40辆车的最大、最小和平均速度,并以平均速度反应道路的通畅情况:
图 4 不同车道数量下车辆最大、最小和平均速度的变化
由于设计不同道路数量时,车辆的数量保持一致,初始车速也为随机生成,因此采用所有车辆的平均行驶速度作为道路拥挤程度的衡量标准。对比三种车道下的平均速度变化,可以发现所有车辆的最大、最小和平均行驶速度均随着车道数量的增加而提高,且车辆速度数据的波动也被逐渐放大,总体呈现出“均值增加,波动变大的”情况,而这也和实际道路的情况保持一致,即车道越多,对于相同数量的车辆来说,车辆密度就越分散,车辆之间车速不一致导致的减速拥堵情况也就越少,也越能保持更高的行驶速度。
图 5 车道变化下的平均归一化车速变化(从右至左以此为2~4车道)
2、车道数量对于车辆变道的影响
如图 5所示为三种不同车道数量下,每条车道上车辆总数的变化情况:
图 6 不同车道数量下每条车道车辆数的变化
仿真中固定车辆总数为40,因此随着车道的增加,总体上每条车道的车辆数目均呈现减少的现象,并没有出现某条车道车辆数目异常的情况。另外也可以从曲线的上下变化情况看出,当车道数增加,车辆拥堵情况得到改善,车辆变道的频率也得到了降低。如图 6所示的司机的耐心值也可以验证这一点,由于司机的耐心值会在每次降到0时实现变道并更新为0,因此频繁的变道也会给平均耐心值带来比较明显的波动,从图里可以看出,车道增加后司机的耐心平均值的波动逐渐减小,这同样反映出车辆变道频率的下降。
图 7 不同车道数量下司机最大、最小和平均耐心值的变化曲线
3、司机耐心值对车速的影响
前文提到过,司机的耐心值在每次减速时均会减1,当减到0时便会选择变道,因此耐心值的大小会影响到车辆变道的频繁程度,而频繁的变道加塞则可能会导致汇入车道的拥堵,因此为了进一步研究对于道路通畅程度的影响因素,我对耐心值每10个单位为一个分段,分别仿真了2~4车道下的归一化平均车速变化曲线,同样固定车辆的数量为40。由于车道数量不同会导致车速区间存在偏差,故绘制三坐标轴图如下图 7所示:
图 8 不同司机耐心值下车速对比
可以看出在2车道情况下车辆均速和耐心值总体上呈线性相关,3车道情况下也同样呈线性相关,但程度有减小,而当4车道时,则几乎不存在线性相关性。可以看出,随着车道数量的增加,车道的拥堵程度减小,耐心值对于车速提升的影响也逐渐减小。
但是结合前面的分析,我认为这主要还是因为4车道情况下车道本身就并不拥挤,因此会大大削弱耐心值提升带来的影响。为了验证前面的观点,我通过增加车辆数量的方式将4车道下的车道拥堵程度提高,观察此时耐心值对于车速是否会有影响,具体结果如图 8所示。
图 9 两种不同车辆数量下耐心值对于4车道车速的影响
从结果可以看出,当增加了车辆数量,使得4车道下的平均车速降低至0.1左右时,耐心值与车速之间的线性关系又会更加显著。因此结合上面的两个对比实验可以得到结论,在道路较为拥堵时,司机耐心值也即变道的频繁程度,会对道路的整体速度造成较大影响,当司机选择尽可能少的变道加塞时,道路整体的车速也会加快。
而这一点反映到实际生活中,就是司机的变道加塞可能让自己一时的速度更快,但是却会让对汇入车道造成影响,让道路整体变得更为拥堵,所以作为一个合格的司机,大家因具备更高的耐心值,减少非必要的变道加塞,会对拥堵的高速道路起到促进作用。
四、不足与改进
1、没有考虑行驶过程中车道边宽变窄的问题
实际的高速道路中,很多时候会遇到匝道驶出和汇入的情况,会导致部分车辆减速,由于时间原因,在这个仿真模型中暂时没有考虑到这一问题。
2、没有考虑加速度、减速度等因素对于车道拥挤程度的影响
仿真处理实验数据花费时间较多,因此关于其他变量对车道拥挤程度的影响没有来得及考虑。
3、没有考虑更加全面的车道拥挤程度的衡量标准
在上述仿真中,我只选择了车辆的归一化平均速度作为衡量标准,考虑因素还是太为简化了,为了更为全面的分析拥挤程度,除了速度外还应该进一步考虑到车辆的密度、车辆等待时间等因素。
五、总结
本次实验中,我初步学习了Netlogo软件简易直观的编程语法,并通过NetLogo软件建立了一个模拟高速道路“幽灵堵车”现象的仿真模型,结合自己的驾驶经历分析了这种现象的影响因素与解决方案,并对车道数量和司机耐心值对交通流畅度的影响进行了仿真探究。在模型设计中,我综合考虑了道路环境和车辆行为等因素,使得模拟结果更加贴近实际情况。
在调节车道数量方面,我观察到随着车道数量的增加,车辆的平均行驶速度呈现上升趋势,同时车速数据的波动也随之放大。这表明车道数量对于交通流畅度有着重要影响,车道越多,车辆之间的拥挤程度相对较低,整体车速也更快。
另外,我分析了司机耐心值对车速的影响。结果显示,在道路较为拥堵时,司机耐心值对车速的影响较大,耐心值越高,车辆变道的频率越低,道路整体的车速也会更快。这提醒我们在实际驾驶中,保持耐心、减少频繁变道加塞对于缓解交通拥堵有着积极作用。
通过对模型的改进和不足的反思,我认识到在进一步研究中还可以加入更多的外部影响因素,如匝道驶出和汇入、加速度、减速度等,以及更细致地评估车道拥挤程度的标准,如车辆密度、等待时间等因素。这将有助于提高模型的准确性和实用性,更好地理解和研究高速道路交通堵车现象。
六、附录
动图演示:
完整代码:
globals [selected-car ; 当前选择的汽车lanes ; 不同车道的y坐标列表
]turtles-own [speed ; 当前速度top-speed ; 最大速度target-lane ; 目标车道patience ; 驾驶员耐心值
]to setupclear-allset-default-shape turtles "car"draw-roadcreate-or-remove-carsreset-ticks
endto create-or-remove-cars;删除大于设置数量的车辆let road-patches patches with [ member? pycor lanes ]if number-of-cars > count road-patches [set number-of-cars count road-patches]create-turtles (number-of-cars - count turtles) [;设置汽车的颜色为指定的蓝色域附近的颜色set color car-color;假设有一个 free road-patches 的集合,在下面的函数中进行判断其中包含了所有空闲的道路地块。;通过 one-of 函数,从这个集合中随机选择一个地块,并使用 move-to 命令让当前的乌龟移动到该地块上。move-to one-of free road-patchesset target-lane pycorset heading 90set top-speed 0.5 + random-float 0.5set speed 0.5set patience random max-patience];判断当前车辆的数量是否大于设定的number of cars如果大于则删除超过数量的turtlesif count turtles > number-of-cars [let n count turtles - number-of-carsask n-of n [ other turtles ] of selected-car [ die ]]
end; 到道路地块中没有其他乌龟的地块,并将这些空闲地块报告出来。
to-report free [ road-patches ]let this-car selfreport road-patches with [not any? turtles-here with [ self != this-car ]]
end;绘制道路
to draw-roadask patches [set pcolor green - random-float 0.5]set lanes n-values number-of-lanes [ n -> number-of-lanes - (n * 2) - 1 ]ask patches with [ abs pycor <= number-of-lanes ] [set pcolor grey - 2.5 + random-float 0.25]draw-road-lines
end;绘制道路的指示线
to draw-road-lineslet y (last lanes) - 1 ; start below the "lowest" lanewhile [ y <= first lanes + 1 ] [if not member? y lanes [; draw lines on road patches that are not part of a laneifelse abs y = number-of-lanes[ draw-line y yellow 0 ] ; yellow for the sides of the road[ draw-line y white 0.5 ] ; dashed white between lanes]set y y + 1 ; move up one patch]
endto draw-line [ y line-color gap ]; We use a temporary turtle to draw the line:; - with a gap of zero, we get a continuous line;; - with a gap greater than zero, we get a dasshed line.create-turtles 1 [setxy (min-pxcor - 0.5) yhide-turtleset color line-colorset heading 90repeat world-width [pen-upforward gappen-downforward (1 - gap)]die]
end;驱动函数
to gorepeat 100 [create-or-remove-carsask turtles [ move-forward ]ask turtles with [ patience <= 0 ] [ choose-new-lane ]ask turtles with [ ycor != target-lane ] [ move-to-target-lane ]tick]
end;前进策略
to move-forward ; turtle procedureset heading 90speed-up-car ; we tentatively speed up, but might have to slow downlet blocking-cars other turtles in-cone (1 + speed) 180 with [ y-distance <= 1 ]let blocking-car min-one-of blocking-cars [ distance myself ]if blocking-car != nobody [; match the speed of the car ahead of you and then slow; down so you are driving a bit slower than that car.set speed [ speed ] of blocking-carslow-down-car]forward speed
end;减速策略,每次减速都会消耗耐心
to slow-down-car ; turtle procedureset speed (speed - deceleration)if speed < 0 [ set speed deceleration ]set patience patience - 1
end;加速策略
to speed-up-car ; turtle procedureset speed (speed + acceleration)if speed > top-speed [ set speed top-speed ]
end;选择新线路,每次换到新线路之后耐心会恢复到最大值
to choose-new-lane ; turtle procedure; Choose a new lane among those with the minimum; distance to your current lane (i.e., your ycor).let other-lanes remove ycor lanesif not empty? other-lanes [let min-dist min map [ y -> abs (y - ycor) ] other-laneslet closest-lanes filter [ y -> abs (y - ycor) = min-dist ] other-lanes;随机选择离自己最近的一个车道,作为变道的目标车道set target-lane one-of closest-lanesset patience max-patience]
end;变道策略
to move-to-target-lane ; turtle procedureset heading ifelse-value target-lane < ycor [ 180 ] [ 0 ]let blocking-cars other turtles in-cone (1 + abs (ycor - target-lane)) 180 with [ x-distance <= 1 ]let blocking-car min-one-of blocking-cars [ distance myself ]ifelse blocking-car = nobody [forward 0.2set ycor precision ycor 1 ; to avoid floating point errors] [;若后方车辆拥堵则减速,否则加速ifelse towards blocking-car <= 180 [ slow-down-car ] [ speed-up-car ]]
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
to-report x-distancereport distancexy [ xcor ] of myself ycor
endto-report y-distancereport distancexy xcor [ ycor ] of myself
endto select-car; allow the user to select a different car by clicking on it with the mouseif mouse-down? [let mx mouse-xcorlet my mouse-ycorif any? turtles-on patch mx my [ask selected-car [ set color car-color ]set selected-car one-of turtles-on patch mx myask selected-car [ set color red ]display]]
endto-report car-color; give all cars a blueish color, but still make them distinguishablereport one-of [ blue cyan sky ] + 1.5 + random-float 1.0
end
这篇关于基于Netlogo的高速道路“幽灵堵车”模型研究的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!