3、交通需求建模:交通流理论简介、OD矩阵概念、flow与route定义、随机交通生成

好,咱们进入第三章。这一章我把它叫做「交通仿真的灵魂」。

为什么这么说?你想想看,路网建得再漂亮,信号灯配得再花哨,如果没有车在上面跑,那就是个空壳子。车怎么来、往哪去、什么时候出发——这些就是交通需求建模要解决的问题。

我个人习惯把这一章分成四个台阶:先搞懂交通流的基本规律,再理解OD矩阵这个核心概念,然后学会在SUMO里定义flow和route,最后玩转随机交通生成。咱们一个一个来。

3.1 交通流理论简介:别被名字吓到

交通流理论,说白了就是研究「车流」的物理规律。你开车堵在路上时,有没有想过为什么车一多速度就上不去?这就是交通流理论要回答的问题。

三个核心参数,记住就行:

  • 流量(Flow):单位时间内通过某断面的车辆数,单位veh/h。我习惯叫它「车流密度」。
  • 密度(Density):单位长度路段上的车辆数,单位veh/km。密度高了,车距就小了。
  • 速度(Speed):车辆的平均行驶速度,单位km/h。

它们之间有个基本关系:流量 = 密度 × 速度。嗯,就这么简单。但实际中你会发现,速度会随着密度增加而下降——这就是所谓的「速度-密度关系」。

我在项目中遇到过一个典型场景:某城市快速路,早高峰时密度达到80veh/km,速度从80km/h掉到20km/h,流量反而下降了。这就是「过饱和」状态——车太多,谁也走不快。

在SUMO里,你不需要手动算这些。但理解这个关系,能帮你判断仿真结果是否合理。比如你设了一个每小时2000辆的流量,结果路网里堵成一锅粥——那说明你的路网容量不够,或者流量设得太高了。

3.2 OD矩阵概念:从哪来到哪去

OD矩阵,全称是Origin-Destination Matrix。说白了就是一张表,记录着「从哪个区域出发,要去哪个区域」的车流量。

举个例子:

出发\到达 区域A 区域B 区域C
区域A 100 300 200
区域B 250 50 400
区域C 150 350 80

这个表的意思是:从区域A到区域B,每小时有300辆车。从区域B到区域C,每小时有400辆车。对角线上的数字(比如区域A到区域A)表示区域内出行。

避坑指南:我曾经在做一个城市级仿真时,OD矩阵里把区域A到区域B的流量写反了,结果仿真出来的交通流向完全不对。检查了三天才发现是矩阵转置的问题。所以,拿到OD矩阵后,先手动验证几个关键对的值。

在SUMO里,OD矩阵通常不会直接写进代码。你需要把它转换成flow或route定义。怎么转?往下看。

3.3 flow与route定义:让车跑起来

在SUMO里,有两种方式定义车辆怎么走:flow和route。

route:定义一条具体的路径。比如「从edge1出发,经过edge2、edge3,到达edge4」。每个车辆都走同一条路。

flow:定义车流。你只需要指定出发边、到达边、流量大小,SUMO会自动为每辆车计算路径。

我个人更推荐用flow,尤其是做大规模仿真时。为什么?因为route需要你手动指定每一条路径,而flow只需要OD对,SUMO会利用Dijkstra算法自动找最短路径。

来看一个flow定义的例子:

<routes>
  <vType id="car" accel="2.6" decel="4.5" sigma="0.5" length="4.5" maxSpeed="50"/>
  
  <flow id="flow_AB" type="car" from="edge_A" to="edge_B" begin="0" end="3600" vehsPerHour="500"/>
  <flow id="flow_BC" type="car" from="edge_B" to="edge_C" begin="0" end="3600" vehsPerHour="300"/>
</routes>

这段代码的意思是:从edge_A到edge_B,每小时500辆车,持续1小时。从edge_B到edge_C,每小时300辆车。

注意:vehsPerHour是流量参数,但SUMO实际生成车辆时会考虑随机性。如果你想要精确控制车辆数,可以用number参数代替。

如果你需要更复杂的路径,比如车辆必须经过某些特定路段,那就用route:

<routes>
  <route id="route_1" edges="edge_A edge_B edge_C edge_D"/>
  <vehicle id="veh_1" type="car" route="route_1" depart="0"/>
  <vehicle id="veh_2" type="car" route="route_1" depart="10"/>
</routes>

嗯,这里每个车辆都要单独定义出发时间。如果车多,写起来很累。所以大规模仿真时,我几乎只用flow。

3.4 随机交通生成:让仿真更真实

真实世界的交通不是均匀的。车流有高峰有低谷,有随机波动。SUMO提供了几种随机化手段:

  • 随机出发时间:用departPos="random"让车辆在路段上随机位置出发。
  • 随机速度:通过speedFactor参数让每辆车的速度在基准值附近波动。
  • 随机路径:用routeDistribution让车辆从多条路径中随机选择。
  • 随机流量:用poisson分布生成车辆到达时间间隔。

来看一个带随机性的flow定义:

<routes>
  <vType id="car" accel="2.6" decel="4.5" sigma="0.5" length="4.5" maxSpeed="50" speedFactor="0.9" speedDev="0.1"/>
  
  <flow id="flow_AB" type="car" from="edge_A" to="edge_B" begin="0" end="3600" vehsPerHour="500" departPos="random"/>
</routes>

这里speedFactor="0.9" speedDev="0.1"的意思是:每辆车的速度会在基准速度的0.9倍附近波动,标准差为0.1。也就是说,有的车开得快,有的车开得慢——这才像真实路况嘛。

我曾经做过一个高速公路仿真,一开始所有车都按统一速度跑,结果仿真出来的交通流跟流水线似的,一点都不真实。后来加了随机速度因子,车流开始出现自然的跟驰和变道行为,仿真结果跟实测数据对上了。

还有一个常用的随机化手段是poisson分布。在SUMO里,你可以用flow的poisson属性:

<flow id="flow_AB" type="car" from="edge_A" to="edge_B" begin="0" end="3600" vehsPerHour="500" departPos="random" poisson="true"/>

加上poisson="true"后,车辆到达时间间隔服从泊松分布。这意味着什么?有时候两辆车几乎同时到达,有时候间隔好几秒——这才是真实交通的随机性。

知识体系总览

下面这张图,是我自己梳理的本章知识结构。你可以把它当作一个导航图:

交通需求建模知识体系 交通流理论 OD矩阵概念 flow与route定义 随机交通生成 流量 · 密度 · 速度关系 速度-密度下降规律 过饱和状态判断 出发-到达区域对应 流量矩阵表示法 转置检查防坑 route:固定路径 flow:OD对+自动寻路 vehsPerHour vs number 随机出发位置 速度因子波动 泊松分布到达 核心逻辑:OD矩阵 → flow定义 → 随机化参数 → 真实交通流 理论指导参数设置,参数设置决定仿真质量

好,这一章的内容就到这儿。交通需求建模是仿真的起点,也是决定仿真质量的关键。你想想看,如果OD矩阵不准,后面的信号优化、排放计算全都是空中楼阁。所以,花时间把这一章的内容吃透,后面的路就好走了。

我的个人习惯:每次新建仿真项目,我都会先画一张OD矩阵的草图,哪怕只有三个区域。然后对照着写flow定义,最后加随机参数。这样一步步来,不容易出错。

可可精品资料库