导致重路由的功能#
有多种模拟功能允许在模拟时进行路由。如下所述:
由车辆触发的路由#
这种类型的路由通过为部分或全部车辆分配重路由设备来实现。详情请参见 Demand/Automatic_Routing。
不完整的行程和流量#
这是上述方法的一个特例。具有不完整路线的车辆会自动接收重路由设备,并在进入网络时进行一次重路由。在某些场景下,这是一种实用的“一次性”路线分配方法,可以避免耗时的迭代分配。
替代路线标志#
这是一种基于位置的触发重路由的方法,描述于 Simulation/Rerouter。
TraCI#
使用方法 traci.vehicle.changeTarget 或 traci.vehicle.rerouteTraveltime 可以为指定车辆触发重路由。
或者,可以使用 traci.simulation.findRoute 计算路线,并使用 traci.vehicle.setRoute 应用路线。
对于人员,可以使用函数 traci.simulation.findIntermodalRoute 来计算简单的步行以及公共交通的行程。
替代目的地#
通过使用 <rerouter>-定义,车辆可以被路由到替代目的地。另一种方法是使用交通分配区 (TAZ)。这允许车辆将其目的地更改为潜在目的地列表中的最佳替代目的地。
处理临时障碍物#
通过使用类型为 <closingReroute allow="..."/> 的 <rerouter>-定义(或者如果所有车道都关闭,则使用 <closingLaneReroute allow="..."/>),可以临时更改道路许可(即模拟施工区域)。默认情况下,当加载的路线穿过已关闭的边,或者由于障碍物导致无法路由到目的地时,模拟会报错。
通过设置包含位标志 traci.constants.ROUTING_MODE_IGNORE_TRANSIENT_PERMISSIONS 的车辆路由模式,可以更改此行为。车辆将忽略障碍物,直到到达关闭的边,然后在那里等待(在达到 --time-to-teleport 后可能会瞬移)。
设置路由模式(以忽略阻塞)可以通过以下方式完成:
traci.vehicle.setRoutingMode(vehID, traci.constants.ROUTING_MODE_IGNORE_TRANSIENT_PERMISSIONS)- sumo 选项 --device.rerouting.mode 8
- 在
vType或单个<vehicle>, <trip>或<flow>中定义<param key="device.rerouting.mode value="8">。
路由的行程时间值#
默认情况下,选择行程时间最短的路线。行程时间取决于当前的路由模式(可通过 traci.vehicle.setRoutingMode 配置)或通过 traci.simulation.findRoute 的显式 routingMode 参数。
路由模式 traci.constants.ROUTING_MODE_DEFAULT#
按以下步骤顺序检索每条边的行程时间。如果某一步提供了数据,则使用该数据,否则尝试下一步:
- 车辆检索其个人数据存储。这可以使用 TraCI 车辆方法 change edge travel time information 和 edge travel time information 进行设置和检索。
- 检索使用选项 --weight-files 加载的全局边权重。
- 检索通过 TraCI 边方法 change edge travel time information 和 edge travel time information 设置和检索的全局边权重。
- 使用最小行程时间(长度/允许速度)。
Note
情况 1-3 的边权重支持模拟边行程时间随时间的变化。这意味着在路由时可以考虑车辆路线上未来行程时间的变化。
路由模式 traci.constants.ROUTING_MODE_AGGREGATED#
使用为重路由设备计算的平滑行程时间。注意,这些也可以通过 TraCI 修改。
随机化行程时间#
Sumo 和 duarouter 支持选项 --weights.random-factor FLOAT。设置此选项后,用于路由的边权重(即行程时间)会受到来自 [1,FLOAT) 的均匀分布随机因子的动态干扰。FLOAT 的值设定了实际最快路径与路由结果之间行程时间差异的上限。当值为 2 时,结果的行程时间/成本在最坏情况下是最优路径的两倍(在极少数情况下,最快路径的所有边都恰好受到因子 2 的干扰)。
随机化边权重在网格网络中很有用,因为那里有许多路径具有相同(或几乎相同)的行程成本,默认路由算法会将所有车辆发送到同一条路径上。它也可用于模拟行程时间估算中的不完美。
Caution
默认情况下,使用相同输入的运行仍将产生相同的结果。要在运行之间改变随机性,必须使用选项 --seed 或 --random。
特殊情况#
- 当使用重路由设备进行重路由时,行程时间总是来自另一个数据存储,该存储通过可配置的平均过程不断更新。此更新策略的参数是用户可定义的。也可以通过 TraCI 直接设置设备行程时间。
- 当使用 python TraCI 库 中的 TraCI 方法 rerouteTraveltime 时,该命令支持一个额外的布尔参数 currentTravelTime(默认为 True)。当此参数设置为 True 时,车辆将临时使用 ROUTING_MODE_AGGREGATED。
按行程时间和边优先级路由#
有时,在仍然考虑行程时间的情况下,使用附加信息来引导路线搜索是很有用的。 对于此用例,可以使用选项 --weights.priority-factor FLOAT,适用于 sumo 和 duarouter。
设置此选项后,每条边的优先级值将被纳入路由决策中,因此低优先级边会受到惩罚(它们看起来更慢),而高优先级边则很少或没有惩罚。对于选项值 PriorityFactor,惩罚计算如下:
MinEdgePriority : 所有边的最小优先级值
MaxEdgePriority : 所有边的最大优先级值
EdgePriorityRange = MaxEdgePriority - MinEdgePriority
relativeInversePrio = 1 - ((edgePriority - MinEdgePriority) / EdgePriorityRange)
effort = traveltime * (1 + relativeInversePrio * PriorityFactor)
结果是:
- 最高优先级的边将不受惩罚
- 最低优先级边的行程时间乘以 1+PriorityFactor
- 具有中间优先级的边将按比例受到惩罚
Caution
选项 -weights.priority-factor 不适用于行人和多模式路由。要为此类路由自定义边偏好,请使用偏好。
按行程时间和 routingType 路由#
有时,在仍然考虑行程时间的情况下,为不同的车辆类别或车辆类型自定义路线搜索是很有用的。
对于此用例,可以使用选项 --additional-files 从附加文件加载元素 <preference>。偏好使用以下属性定义:
| 属性名 | 值类型 | 描述 |
|---|---|---|
| routingType | id (string) | routingType 或边的类型 |
| priority | float > 0 | 具有该 routingType 的边的优先级值 |
| vTypes | id list | 应用此偏好的车辆类型列表 |
| vClasses | id list | 应用此偏好的车辆类别列表 |
当 <preference> 元素被加载时,所有列出的 vTypes 和 vClasses 的边行程时间将除以定义的 priority 值,适用于所有具有给定 routingType 的边。如果边未定义属性 routingType,则使用其 type 来匹配偏好。
示例:
<additional >
<preference routingType="typeB" vClasses="wheelchair" priority="4"/>
</additional>
Note
如果 <preference> 元素既未定义 vTypes 也未定义 vClasses,它将把 priority 应用于所有车辆/人员。
按努力路由#
默认情况下,路由算法的目标是最小化起点和终点之间的行程时间。 行程时间可以根据速度限制和车辆最高速度计算,可以在运行时根据模拟状态估算,也可以从数据文件加载。后一种选项允许为未来定义行程时间。未来行程时间相关性的一个例子如下:
- 一辆车辆在没有拥堵的时候出发进行长途旅行
- 已知网络的部分区域稍后会发生拥堵
- 在出发时计算的车辆路线可以避开拥堵,因为路由算法知道在到达那些边时它们会发生拥堵。
除了行程时间(距离、排放、价格等)之外,最小化其他标准(称为努力)来计算路线可能是有用的。 当这些量随时间变化时,路由算法需要每条边的两种值:
- 应最小化的努力
- 边的行程时间。
行程时间用于计算在何时到达某条边,以便正确使用随时间变化的努力值。
Note
当努力值不随时间变化时,可以通过加载修改了 traveltime 属性的权重文件(将努力值写入 traveltime 属性)来实现按努力路由,并且可以省略选项 --weight-attribute。
当设置选项 --weight-file 和 --weight-attribute 时,会根据指定的属性读取额外的路由努力。这些仅在调用 TraCI 函数 按努力重路由 时使用。车辆路线上的假定努力是基于时间的值,时间是根据上述行程时间值计算的。也可以使用 traci.edge.setEffort 设置努力值。
Caution
默认努力值为 0,这会导致在未加载合理的努力值时优先选择绕行路线。
应用程序 duarouter 和 marouter 也支持选项 --weight-file 和 --weight-attribute,这可用于读取给定文件中的任何边属性值。
按距离路由#
寻找最短路线而不是最快路线,可以通过加载合适的努力数据(见 #按努力路由)或将所有网络边的速度设置为相同值来实现。
一个更简单的解决方案是定义一个在所有边上以相同速度行驶的车辆类型:
<vType id="routeByDistance" maxSpeed="1"/>
然后使用该类型来寻找最快路线:
stageResult = traci.simulation.findRoute(fromEdge, toEdge, "routeByDistance")
shortestDistance = stage.length
Note
旧版本的 SUMO 不提供值 stage.length。在这种情况下,shortestDistance = stage.travelTime 也是正确的,因为速度为 1m/s。
路由算法#
执行路由的应用程序(sumo, sumo-gui, duarouter, marouter)支持选项 --routing-algorithm 来选择以下值:
dijkstra#
Dijkstras 算法是最简单也是最慢的路由算法。它非常适合于时间依赖网络中的路由(即当边上的行程时间取决于一天中的时间时)。
Note
这是默认算法。
astar (A*)#
A* 路由算法使用一个度量来约束行程时间以引导搜索,通常比 dijkstra 更快。这里使用的度量是 欧几里得距离 / 最大车辆速度)。
ALT#
通过将 astar 与选项 --astar.landmark-distances <FILE> 结合使用,可以激活 ALT 算法。 ALT 代表:A*, Landmarks(地标), triangle inequality(三角不等式)。 它使用预先计算的距离表(针对选定的网络边,即所谓的地标)来加速搜索,通常效果显著。
- 可以通过创建一个每行包含一个地标边 id 的文件(例如 landmarks.txt)来生成查找表,然后设置选项 --astar.landmark-distances landmarks.txt --astar.save-landmark-distances lookuptable.txt。
- 生成距离表的替代输入是每行一个地理坐标,格式为
LON LAT- 工具 generateLandmarks.py 可用于通过在网络边缘的所有方向上分布边来生成地标输入文件 - 作为经验法则,在网络边界的主要道路上分布 8-16 条边可以实现良好的 ALT 性能。不建议使用更多边,因为每个地标都会增加固定开销。
- 通过将 astar 与选项 --astar.all-distances <FILE> 结合使用,A* 算法与一个完整(通常很大)的距离表一起使用,以实现极快的搜索。这仅推荐用于具有大量路由查询的中等规模网络。
Caution
当计划使用选项 --weights.priority-factor 或 --weights.random-factor 进行路由时,预计算的距离表没有用,因为这些选项会改变实际距离。
CH (Contraction Hierarchies,收缩层次结构)#
收缩层次结构 是一种基于预处理的路由算法。当预期有大量查询时,这非常高效。该算法不考虑时间依赖的权重。相反,可以通过设置选项 --weight-period <TIME> 为固定大小的时间片执行新的预处理。
当加载具有边许可的网络时,会在路由任务中遇到的每个车辆类别触发单独的预处理(通过自动切换到 CHWrapper)。
CHWrapper#
这与 CH 类似,但会为遇到的每个车辆类别执行单独的预处理,从而在多模式场景中实现路由。
影响路由的其他选项#
- --weights.minor-penalty FLOAT :为通过无通行权的路口设置固定的时间惩罚(默认 1.5s)
- --persontrip.walk-opposite-factor FLOAT :设置逆车流步行时的速度惩罚因子(参见行人路由)(默认 1)
