You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用aequilibrae进行多类交通分配时的维度不匹配错误解决

多类交通均衡分配中不同Graph形状导致的ValueError解决

问题描述

使用Python的aequilibrae包执行多类交通均衡分配时,调用assig.execute()后抛出ValueError: operands could not be broadcast together with shapes (11202,) (9184,)。原因是不同交通类使用了不同结构的网络(对应g_usa、g_china、g_neutral三个Graph,节点/边数量不一致)。

脚本片段

%%time

aem_usa = AequilibraeMatrix()
aem_china = AequilibraeMatrix()
aem_neutral= AequilibraeMatrix()

os.chdir("D:/Professional/Mir/1_multi_class_analysis/7_matrix_bin/") #setting directory

#load aem file
aem_usa.load("Demand_usa.aem")
aem_usa.computational_view(["matrix"])

aem_china.load("Demand_china.aem")
aem_china.computational_view(["matrix"])

aem_neutral.load("Demand_neutral.aem")
aem_neutral.computational_view(["matrix"])

#now assign classes
tc_usa= TrafficClass("usa_flow", g_usa, aem_usa)
tc_china=TrafficClass("china_flow", g_china, aem_china)
#tc_china.set_pce(1)
tc_neutral= TrafficClass("neutral_flow", g_neutral, aem_neutral)

#set classes
assig= TrafficAssignment()
assig.set_classes([tc_china, tc_neutral])
assig.set_vdf("BPR")
assig.set_vdf_parameters({"alpha":0, "beta":1})
assig.set_capacity_field("capacity")
assig.set_algorithm("all-or-nothing")
assig.max_iter = 100
assig.rgap_target = 1e-6
assig.execute()

错误信息

{
    "name": "ValueError",
    "message": "operands could not be broadcast together with shapes (11202,) (9184,) ",
    "stack": "---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
File <timed exec>:36

File c:\Users\Raisul\anaconda3\envs\my_env\Lib\site-packages\aequilibrae\paths\traffic_assignment.py:432, in TrafficAssignment.execute(self, log_specification)
    430 if log_specification:
    431     self.log_specification()
--> 432 self.assignment.execute()

File c:\Users\Raisul\anaconda3\envs\my_env\Lib\site-packages\aequilibrae\paths\linear_approximation.py:388, in LinearApproximation.execute(self)
    384 self.__maybe_create_path_file_directories()
    386 for c in self.traffic_classes:  # type: TrafficClass
    387     # cost = c.fixed_cost / c.vot + self.congested_time #  now only once
--> 388     cost = c.fixed_cost + self.congested_time
    389     aggregate_link_costs(cost, c.graph.compact_cost, c.results.crosswalk)
    391     aon = allOrNothing(c.matrix, c.graph, c._aon_results)

ValueError: operands could not be broadcast together with shapes (11202,) (9184,) "
}

解决方案(保留不同Graph形状的前提下)

aequilibrae的多类交通分配默认要求所有交通类共享同一基础网络结构(即所有Graph的边数、节点映射必须一致),因为分配过程中需要统一计算拥堵时间等全局变量。要在保留不同Graph的前提下完成分配,可采用以下两种思路:

1. 拆分独立分配,手动合并结果

对每个交通类单独执行交通分配,再将各类型的流量结果合并到统一的网络中:

# 定义通用分配配置函数
def run_single_class_assignment(traffic_class):
    assig = TrafficAssignment()
    assig.set_classes([traffic_class])
    assig.set_vdf("BPR")
    assig.set_vdf_parameters({"alpha":0, "beta":1})
    assig.set_capacity_field("capacity")
    assig.set_algorithm("all-or-nothing")
    assig.max_iter = 100
    assig.rgap_target = 1e-6
    assig.execute()
    return assig

# 分别执行三类分配
assig_usa = run_single_class_assignment(tc_usa)
assig_china = run_single_class_assignment(tc_china)
assig_neutral = run_single_class_assignment(tc_neutral)

# 手动合并结果(需确保各网络的边有唯一标识可匹配)
# 示例:假设所有网络的边都有相同的'link_id'字段
# 先获取各分配结果的边流量数据
usa_flows = assig_usa.results.get_link_flows()
china_flows = assig_china.results.get_link_flows()
neutral_flows = assig_neutral.results.get_link_flows()

# 合并到统一DataFrame
merged_flows = usa_flows.merge(china_flows, on='link_id', how='outer', suffixes=('_usa', '_china'))
merged_flows = merged_flows.merge(neutral_flows, on='link_id', how='outer', suffixes=('', '_neutral'))
merged_flows.fillna(0, inplace=True)

2. 构建统一超网络,适配所有交通类

将三个不同的网络合并为一个包含所有边的超网络,然后为每个交通类设置对应的边通行规则(比如对某类不可通行的边设置无穷大成本或0容量):

# 假设三个网络都是从同一基础GeoDataFrame衍生的,先合并所有边
import pandas as pd
from aequilibrae.paths import Graph

# 合并三个网络的边数据(需确保字段一致)
combined_edges = pd.concat([g_usa.network, g_china.network, g_neutral.network]).drop_duplicates(subset='link_id')

# 创建统一超网络的Graph
g_combined = Graph()
g_combined.load_from_geodataframe(combined_edges, directed=True)

# 为每个交通类设置专属成本:对该类不可通行的边设置极高成本
# 示例:USA类只能走g_usa的边,其他边成本设为1e10
tc_usa = TrafficClass("usa_flow", g_combined, aem_usa)
# 获取g_usa的link_id集合
usa_link_ids = set(g_usa.network['link_id'])
# 筛选出超网络中不属于USA的边,设置成本为极大值
non_usa_indices = g_combined.network[~g_combined.network['link_id'].isin(usa_link_ids)].index
tc_usa.graph.free_flow_time.iloc[non_usa_indices] = 1e10

# 同理处理China和Neutral类
tc_china = TrafficClass("china_flow", g_combined, aem_china)
china_link_ids = set(g_china.network['link_id'])
non_china_indices = g_combined.network[~g_combined.network['link_id'].isin(china_link_ids)].index
tc_china.graph.free_flow_time.iloc[non_china_indices] = 1e10

tc_neutral = TrafficClass("neutral_flow", g_combined, aem_neutral)
neutral_link_ids = set(g_neutral.network['link_id'])
non_neutral_indices = g_combined.network[~g_combined.network['link_id'].isin(neutral_link_ids)].index
tc_neutral.graph.free_flow_time.iloc[non_neutral_indices] = 1e10

# 现在执行多类分配
assig = TrafficAssignment()
assig.set_classes([tc_china, tc_neutral, tc_usa])
assig.set_vdf("BPR")
assig.set_vdf_parameters({"alpha":0, "beta":1})
assig.set_capacity_field("capacity")
assig.set_algorithm("all-or-nothing")
assig.max_iter = 100
assig.rgap_target = 1e-6
assig.execute()

# 获取合并后的各类流量结果
combined_results = assig.results.get_link_flows()

关键说明

  • 第一种方法更直接,适合各网络重叠度低的场景,但无法模拟不同类流量之间的拥堵相互影响(因为是独立分配)。
  • 第二种方法能保留多类分配的拥堵交互效果,但需要确保超网络的边标识统一,且正确设置各类的通行限制。

内容的提问来源于stack exchange,提问作者MIr Raisul Islam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 19:24:59