一、算法原理
代码基于结构可控性理论自动识别需要安装传感器的节点位置。核心思想:
- 水流方向决定信息传播方向
- 传感器应放置在能"控制"整个网络的节点上
- 通过最大匹配算法找出最少的传感器节点集合
二、整体流程
EPANET文件(INP/RPT) → 解析拓扑结构 → 解析水流数据 → 构建反向流图 → 最大匹配分析 → 输出传感器节点
三、详细步骤分解
1. 文件读取阶段 (第24-53行)
python
def get_input_paths():
inp_file = find_file_case_insensitive(MAP_DIR, "network.inp") # 网络拓扑
rpt_file = find_file_case_insensitive(MAP_DIR, "network.rpt") # 水力模拟结果
bin_file = find_file_case_insensitive(MAP_DIR, "network.bin") # 可选
支持的EPANET文件格式:
.inp: 包含管网拓扑结构(节点、管道、水泵、阀门).rpt: 包含水力模拟结果(各时段流量).bin: 二进制结果文件(当前未解析)
2. 拓扑解析 (第56-111行)
解析INP文件,识别关键部分:
- 管道(SECTIONS): PIPES, PUMPS, VALVES
- 节点类型: JUNCTIONS, RESERVOIRS, TANKS
python
# 示例:解析一条管道
# [PIPES]
# PIPE-1 J-1 J-2 300 12 ...
# => link_id="PIPE-1", from="J-1", to="J-2"
3. 流量数据解析 (第114-199行)
从RPT文件中提取各时段的流量数据:
Link Results at 0:00:00 hrs:
Link Flow Velocity ...
PIPE-1 12.3 0.85
PIPE-2 -5.6 0.42
关键点:
- 正流量:水流从
from_node→to_node - 负流量:水流从
to_node→from_node
4. 构建反向流图 (第202-241行)
核心创新:将水流方向反转构建有向图
python
# 反向规则:
if flow > 0: # 水流从u→v
graph.add_edge(v, u) # 反向边v→u
elif flow < 0: # 水流从v→u
graph.add_edge(u, v) # 反向边u→v
else: # 零流量
# 两端都需要安装传感器
zero_flow_sensor_nodes.add(u)
zero_flow_sensor_nodes.add(v)
物理意义:
- 污染物随水流向下游扩散
- 传感器若在上游,可以检测到从下游传来的污染信号(反向传播)
- 因此反向边代表"可观测性"方向
5. 最大匹配分析 (第244-284行)
这是理论核心:通过二分图最大匹配找出驱动节点
python
def driver_nodes_by_maximum_matching(graph: nx.DiGraph):
# 构建二分图:左侧L节点,右侧R节点
# 边L_u → R_v 对应原图中的 u→v
# 最大匹配后,右侧未匹配的节点 = 驱动节点
unmatched_nodes = all_nodes - matched_right
# 如果完美匹配,选择任意一个节点
if not unmatched_nodes and all_nodes:
unmatched_nodes = {next(iter(all_nodes))}
理论意义:
- 驱动节点就是需要放置传感器/控制器的位置
- 通过控制这些节点可以影响整个网络的状态
6. 多时段整合 (第315-335行)
python
for step_index, flow_map in enumerate(flows_by_time):
# 每个时段分别计算驱动节点
drivers = driver_nodes_by_maximum_matching(graph)
final_driver_nodes.update(drivers) # 取并集
# 收集零流量管道的两端
zero_flow_sensor_nodes.update([u, v])
考虑因素:
- 不同时段水流方向可能变化(如用水高峰期、夜间)
- 取所有时段的并集确保全天候可观测
- 零流量管道两端都需要传感器(无法确定传播方向)
7. 可视化输出 (第354-426行)
生成两个网络图:
network_original.png: 原始拓扑结构network_sensors.png: 标注候选传感器位置
python
# 传感器节点用大圆点突出显示
nx.draw_networkx_nodes(
G, pos,
nodelist=list(sensor_nodes),
node_size=80, # 正常节点20
alpha=0.95,
)
四、输出结果
文件输出
candidate_sensor_nodes.txt: 传感器候选节点列表(每行一个节点ID)
控制台输出示例
Loaded INP:
nodes: 1247
links: 1456
Parsed RPT time steps: 24
time step 1: drivers=12, zero_flow_links=3, missing_flow_links=0
time step 2: drivers=11, zero_flow_links=5, missing_flow_links=0
...
Final result:
unique driver nodes: 45
zero-flow endpoint nodes: 12
final candidate sensor nodes: 57
五、关键技术特点
- 自适应方向:根据实际水流方向动态调整传感器位置
- 时间效应:考虑不同时段的流量变化
- 鲁棒性:处理缺失数据和零流量情况
- 理论基础:基于结构可控性的严格数学保证
六、潜在改进方向
- 坐标使用 :当前使用弹簧布局,可改用INP中的
[COORDINATES]真实坐标 - 二进制文件 :可扩展解析
.bin文件提高性能 - 成本优化:添加约束条件(如传感器数量限制、安装成本)
- 失效分析:考虑管道故障情况下的鲁棒性
这个算法可广泛应用于自来水管网、燃气管网、化工流程等流体网络的传感器优化布点问题。