《交通规划》——最短路分配方法

《交通规划》——最短路分配方法

说明:下面内容,将用python、networkx实现刘博航、杜胜品主编的《交通规划》P198页的例题,主要是实现最短路径分配方法。

1. 题目描述如下:

IMG_0624

IMG_0625

2. networkx构建网络

import networkx as nx
import matplotlib.pyplot as plt

# 带权重的边列表
edges = [(1,2,10), (1,3,4), (2,3,3), (2,4,5),(3,4,12),
         (2,1,10), (3,1,4), (3,2,3), (4,2,5),(4,3,12)]
nodes = [1,2,3,4]

# 创建无向图
G = nx.DiGraph()

# 添加节点
G.add_nodes_from(nodes)
G.add_weighted_edges_from(edges)

# 绘制图形
pos = nx.spring_layout(G)
nx.draw(G, pos, with_labels=True, node_color='lightblue', node_size=500, font_size=16, font_weight='bold')
labels = nx.get_edge_attributes(G, 'weight')
nx.draw_networkx_edge_labels(G, pos, edge_labels=labels, font_size=12, font_color='red')
plt.show()

nx.write_gexf(G,'./net9_2.gexf')

构建的网络为有向图:

image-20230614195842282

3. 输入OD矩阵,表9-8

import pandas as pd
import numpy as np
od = pd.DataFrame(
    data=
    {'A':[0,100,300],
    'B':[100,0,200],
    'C':[300,200,0]}
)

od.index = ['A', 'B', 'C']
od
od.to_csv('./OD_9-8.csv')

image-20230614200104793

4. 流量分配

思路:

  • 处理OD矩阵,处理成OD对
  • 遍历每一对OD对,找出OD对对应的最短路径,并存储
  • 遍历最短路径所经过的边,将流量分配到对应的边上

4.1 OD矩阵 -->OD对

import pandas as pd
import networkx as nx
import matplotlib.pyplot as plt

#输入网络
G=  nx.read_gexf('./net9_2.gexf')

# 输入OD
od = pd.read_csv('./OD_9-8.csv',index_col=0)
od

# 将OD点和网络节点进行对应
od_map_nodes_dict = {
    'A':1,
    'B':3,
    'C':4
}
# 将OD表处理成OD对
od_new = od.unstack()
od_new = od_new.reset_index()
od_new = od_new.rename(dict(zip(list(od_new.columns),['O','D','q'])),axis=1) #q 表示交通小区之间的出行分布量
od_new

image-20230614200503098

4.2 初始化网络中的流量

# 初始化G中的flow属性
for u,v,data in G.edges(data = True):
    data['flow'] =0

边视图如下:

image-20230614200634972

4.3 遍历每对OD,查找最短路径,并分配流量

#!分配OD量
# 将各OD点对的OD量分配到该OD点对应的最短路径上,并进行累加
df = od_new
# 遍历DataFrame的每一行
for _, row in df.iterrows():
    # 获取流量
    flow = row['q']
    O = str(od_map_nodes_dict[row['O']])
    D = str(od_map_nodes_dict[row['D']])
    # 获取路径
    path = nx.shortest_path(G,O,D,'weight')
    print(row['O'],'-',row['D'],'shortest_path:',path)
    
    # 分配流量到路径上的每一条边
    for i in range(len(path) - 1):
        # 如果边已经存在,增加流量
        if G.has_edge(path[i], path[i+1]):
            if 'flow' in G[path[i]][path[i+1]]:
                G[path[i]][path[i+1]]['flow'] += flow
            else:
                G[path[i]][path[i+1]]['flow'] = flow
        # else:
            # G.add_edge(path[i], path[i+1], flow=flow)

# 输出结果
G.edges(data= True)

for u, v, data in G.edges(data=True):
    print(f"Edge: {u}-{v}, Flow: {data['flow']}")

结果(和书中一致):

image-20230614200809713

IMG_0626

5. 完整代码:

import pandas as pd
import networkx as nx
import matplotlib.pyplot as plt
#************************************************************************************************
od = pd.DataFrame(
    data=
    {'A':[0,100,300],
    'B':[100,0,200],
    'C':[300,200,0]}
)

od.index = ['A', 'B', 'C']
od
od.to_csv('./OD_9-8.csv')

#************************************************************************************************
# 带权重的边列表
edges = [(1,2,10), (1,3,4), (2,3,3), (2,4,5),(3,4,12),
         (2,1,10), (3,1,4), (3,2,3), (4,2,5),(4,3,12)]
nodes = [1,2,3,4]

# 创建无向图
G = nx.DiGraph()

# 添加节点
G.add_nodes_from(nodes)
G.add_weighted_edges_from(edges)

# 绘制图形
pos = nx.spring_layout(G)
nx.draw(G, pos, with_labels=True, node_color='lightblue', node_size=500, font_size=16, font_weight='bold')
labels = nx.get_edge_attributes(G, 'weight')
nx.draw_networkx_edge_labels(G, pos, edge_labels=labels, font_size=12, font_color='red')
plt.show()

nx.write_gexf(G,'./net9_2.gexf')


#************************************************************************************************
#输入网络
G=  nx.read_gexf('./net9_2.gexf')

# 输入OD
od = pd.read_csv('./OD_9-8.csv',index_col=0)
od

# 将OD点和网络节点进行对应
od_map_nodes_dict = {
    'A':1,
    'B':3,
    'C':4
}
# 将OD表处理成OD对
od_new = od.unstack()
od_new = od_new.reset_index()
od_new = od_new.rename(dict(zip(list(od_new.columns),['O','D','q'])),axis=1) #q 表示交通小区之间的出行分布量
od_new

# # 确定最短OD对之间的最短路径
# od_new['shortest_path'] = od_new.apply(lambda x:nx.shortest_path(G,str(od_map_nodes_dict[x['O']]),str(od_map_nodes_dict[x['D']]),weight='weight'),axis=1)
# # 将路径中的节点从字符串转化为整数,因为图G中的节点是整数
# od_new['shortest_path'] = od_new['shortest_path'].apply(lambda x: [int(node) for node in x])


#!分配OD量
# 将各OD点对的OD量分配到该OD点对应的最短路径上,并进行累加
df = od_new
# 初始化G中的flow属性
for u,v,data in G.edges(data = True):
    data['flow'] =0



G.edges(data = True)

#!分配OD量
# 将各OD点对的OD量分配到该OD点对应的最短路径上,并进行累加
df = od_new
# 遍历DataFrame的每一行
for _, row in df.iterrows():
    # 获取流量
    flow = row['q']
    O = str(od_map_nodes_dict[row['O']])
    D = str(od_map_nodes_dict[row['D']])
    # 获取路径
    path = nx.shortest_path(G,O,D,'weight')
    print(row['O'],'-',row['D'],'shortest_path:',path)
    
    # 分配流量到路径上的每一条边
    for i in range(len(path) - 1):
        # 如果边已经存在,增加流量
        if G.has_edge(path[i], path[i+1]):
            if 'flow' in G[path[i]][path[i+1]]:
                G[path[i]][path[i+1]]['flow'] += flow
            else:
                G[path[i]][path[i+1]]['flow'] = flow
        # else:
            # G.add_edge(path[i], path[i+1], flow=flow)

# 输出结果
G.edges(data= True)

for u, v, data in G.edges(data=True):
    print(f"Edge: {u}-{v}, Flow: {data['flow']}")
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/28764.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

WRF进阶:使用ERA5-land数据驱动WRF/WRF撰写Vtable文件添加气象场

想用WRF模拟地气交换过程,对于WRF的地表数据,尤其是土壤温湿度数据要求便会很大,传统使用ERA5-singledata数据精度也许不足以满足需求,为此,本文尝试使用ERA5-land数据替换驱动WRF。 数据下载 ERA5-land的数据下载与…

springboot第27集:springboot-mvc,WxPay

在数据库中,DISTINCT 关键字用于查询去重后的结果集。它用于从查询结果中去除重复的行,只返回唯一的行。 要使用 DISTINCT 关键字,可以将其放置在 SELECT 关键字之前,指示数据库返回去重后的结果。 请注意,DISTINCT 关…

day07--java高级编程:JDK8的新特性,JDK9的新特性,JDK10的新特性,JDK11的新特性,JDK15的新特性

1 JDK8的其它新特性 说明:一些8中的新特性在,java高级部分学习的同时顺便讲过了。 1.1 JDK8新特性的总体结构 1.2 Java 8新特性简介 1.3 Lambda表达式 1.3.1 出现背景 1.3.2 Lambda表达式的使用举例 package com.atguigu.java1;import org.junit.Tes…

AntDB 企业增强特性介绍——AntDB在线数据扩容关键技术

数据库集群安装完成后,其数据存储容量是预先规划并确定的。随着时间的推移以及业务量的增加,数据库集群中的可用存储空间不断减少,面临数据存储容量扩充的需求。 传统的在线扩容的流程大致如下。 (1)在集群中加入新的 …

数据库迁移 | Oracle数据迁移方案之技术两三点

今年Oracle似乎又火了,火得要下掉,目前中国大概有240数据库企业,在国产信创的大趋势下,一片欣欣向荣,国库之春已然来临。到今天为止,Oracle依旧是市场份额最大的数据库,天下苦秦久矣&#xff0c…

【JVM 监控工具】JVisualVM的使用

文章目录 前言二、启动JVisualVM三、安装插件四、使用 前言 JVisualVM是一个Java虚拟机的监控工具,要是需要对JVM的性能进行监控可以使用这个工具哦 使用这个工具,你就可以监控到java虚拟机的gc过程了 那么,这么强大的工具怎么下载呢&…

顶奢好文:3W字,穿透Spring事务原理、源码,至少读10遍

说在前面 在40岁老架构师 尼恩的读者社区(50)中,最近有小伙伴拿到了一线互联网企业如阿里、美团、极兔、有赞、希音的面试资格,Spring事务源码的面试题,经常遇到: (1) spring什么情况下进行事务回滚? (2) spring 事务…

Transformer在CV领域有可能替代CNN吗?

目前已经有基于Transformer在三大图像问题上的应用:分类(ViT),检测(DETR)和分割(SETR),并且都取得了不错的效果。那么未来,Transformer有可能替换CNN吗&#…

索尼RSV视频修复方法论视频文件修复时样本文件的三同

索尼RSV类的文件修复案例有很多,程序操作也很简单没什么可说的,这次这个索尼ILCE-7SM3的案例就是为了让大家更好的认识视频修复中我称之为“三同“的重要性,想要恢复的效果好必须要把准备工作做到位。 故障文件:45.1G RSV文件 故障现象: 索…

工具篇--4 消息中间件-RabbitMq 模型介绍

1 介绍: RabbitMQ 是一个开源的消息中间件,它实现了 AMQP(高级消息队列协议)标准,并且支持多种语言和操作系统,包括 Java、Python、Ruby、PHP、.NET、MacOS、Windows、Linux 等等。RabbitMQ 提供了可靠的消息传递机制…

竞赛无人机搭积木式编程(三)---用户自定义航点自动飞行功能(全局定位,指哪打哪)

竞赛无人机搭积木式编程(三)---用户自定义航点自动飞行功能(全局定位,指哪打哪) 无名小哥 2023年6月10日 用户通过对前面两讲中全国大学生电子设计竞赛真题植保无人机(2021)、送货无人机&#…

【UE 从零开始制作坦克】2-控制坦克移动(简单的移动效果)

效果 步骤 1. 新建蓝图类,父类选择“VehicleWheel(载具车轮)” 这里就命名为“TankWheel” 双击打开“TankWheel”,设置形状半径为40 2. 打开 “BP_West_Tank_M1A1Abrams” 选中“网格体(VehicleMesh)&…

JMeter参数化4种实现方式

目录 前言: 1 参数化释义 2 参数化实现 CSV实例 注意事项 前言: 在使用JMeter进行测试时,参数化允许您模拟不同的用户、不同的数据、不同的操作等,从而增加了测试的灵活性和复用性 1 参数化释义 什么是参数化?…

设计模式(十八):行为型之观察者模式

设计模式系列文章 设计模式(一):创建型之单例模式 设计模式(二、三):创建型之工厂方法和抽象工厂模式 设计模式(四):创建型之原型模式 设计模式(五):创建型之建造者模式 设计模式(六):结构型之代理模式 设计模式…

分布式数据库HBase

大数据基础-分布式数据库HBase 概述HBase简介HBase与传统关系数据库的对比分析 HBase数据模型数据模型概述数据模型相关概念数据坐标 HBase的实现原理HBase功能组件表和RegionRegion的定位HBase框架结构HMasterRegionServerHBase协作组件RegionColumnFamilyKeyValue小结 HBase运…

STM32单片机(六)TIM定时器 -> 第二节:TIM定时中断练习(定时器定时中断和定时器外部时钟)

❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 :适用于想要…

docker数据管理---数据卷,数据卷容器

在Docker中,数据卷(data volumes)和数据卷容器(data volume containers)是用于在容器之间共享和持久化数据的两种不同的机制。 一、数据卷 数据卷是一个特殊的目录或目录,可以绕过容器文件系统的常规层&a…

【RabbitMQ教程】第六章 —— RabbitMQ - 延迟队列

💧 【 R a b b i t M Q 教程】第六章—— R a b b i t M Q − 延迟队列 \color{#FF1493}{【RabbitMQ教程】第六章 —— RabbitMQ - 延迟队列} 【RabbitMQ教程】第六章——RabbitMQ−延迟队列💧 🌷 仰望天空,妳我亦是行人…

2023年前端面试高频考点HTML5+CSS3

目录 浏览器的渲染过程⭐⭐⭐ CSS 、JS 阻塞 DOM 解析和渲染 回流(重排)和重绘⭐⭐ 选择器 ID选择器、类选择器、标签选择器(按优先级高到低排序)⭐⭐ 特殊符号选择器(>,,~,空格&#xff0…

Stopwatch工具类计时器探究

搬砖的我们 特别是Java开发的童鞋们, 经常需要通过记录开始时间和结束时间,然后通过计算差值,得到时间差,如下面的代码: long start System.currentTimeMillis(); long end System.currentTimeMillis(); System.out.println(…