交通规划四阶段法:基于 Python 的交通分布预测算法复现 - 附完整代码链接

我这个学期有交通规划的课程。·交通规划四阶段法中第二阶段即是交通分布预测,需要使用一些常用的算法,常见的像是:

  1. 传统的增长系数方法:平均系数法、底特律法、Frater法、Funess法等
  2. 重力模型:无约束重力模型、单约束重力模型法、双约束重力模型法

我写了一些算法简单的 Python 实现,封装成了 Python 类和函数,以便调用。当然,实际的交通需求预测当中不会真的使用 Python 之类的代码工具来实现,有现成的专用工具,如 TransCAD 等。此处代码仅做一演示,以便 课堂测试计算的时候偷懒 学习交流使用。

到目前为止算法的完成度并不高,只有简单的几个模型。对于已经完成的代码部分,大家可以自行取用。但是 比起分享现在已经完成的代码,我更希望有人可以和我一起合作写代码。因此我将项目发布挂在了 Gitee 平台,理想的话希望可以发展成一个 Python 包。

项目的页面地址:基于 Python 的交通分布预测算法复现

拉取项目的命令:

git clone https://gitee.com/BOXonline_1396529/traffic_distribution_predict.git

我只是想使用这些代码

如果您只是想使用这些代码来学习算法或者完成您的课堂作业,以下是你需要做的事:

下载代码文件

看这篇博客的小伙伴们应该有很多都是和我一样的苦逼交通生,可能从来没有在开放代码平台下载过代码,找不到下载按钮。其实下载按钮就在网页的这个位置:

最近的 Gitee 有点烦人,可能会让你扫码关注公众号注册之类的。稍微应付一下就好了哈。

点击之后会弹出这个窗口:

直接下载 .zip 就是代码的压缩包了。

代码的使用方法

为防止交通专业的同学们不会用这些代码,特此说明:你可以像使用一般的模块那样使用这些代码。确保项目根目录下的 traffic_distribution_predict 目录与您需要调用模块的代码文件(.py.ipynb 等)处于同一目录下。导入需要的工具,这里以福莱特法交通分布预测函数为例:

from traffic_distribution_predict.coefficient_model import frator

然后调用函数:

# 需要计算的数据
# `X` 为 OD 矩阵
# `U` 和 `V` 分别为未来年的生成量与吸引量
X = np.array([[17,7,4],[7,38,6],[4,5,17]])
U = np.array([38.6, 91.9, 36.0])
V = np.array([39.3, 90.3, 36.9])
# `fX` 为未来年 OD 矩阵
fX = frator(X, U, V, alpha=0.05)

具体的用法可以参考项目根目录下的 .\docs\build\html\index.html 文件,双击在浏览器中打开。也可以参考详细的代码注释。

合作

如果您想要参与项目合作,您可以:

  1. 与我取得联系
  2. 提交 Issues
  3. 克隆仓库到本地,编写代码,提交 Pull Requests

部分代码内容的展示

以下是部分代码内容的展示,选取了 无约束重力模型 作为演示。

"""
traffic_distribution_predict.gravity_model
========================================== 实现基于 **重力模型** 的交通分布预测。 在交通分布预测中,重力模型(Gravity model)是一种广泛应用
的模型,其灵感来源于物理学中的万有重力定律。在交通领域,这个
模型用于预测从一个地区到另一个地区的流量(如人口流动、交通流
量等)。 模型假设两地区之间的流量与两地区的吸重力成正比,与两地区之间
的距离的某个函数成反比。
""" import numpy as np import statsmodels.api as sm class unconstrained_gravity_model:
r"""
使用无约束重力模型进行交通分布预测 这个类实现了使用 **无约束重力模型** 进行交通分布预测的功能 无约束重力模型的基本形式(无约束重力模型)可以表示为: .. math:: q_{ij} = k \frac{O_i^{\alpha} O_j^{\beta}
}{C_{ij}^{\gamma}} 无约束重力模型包含 :math:`\alpha`、:math:`\beta`、
:math:`\gamma`,参数通过参数估计方法取得。具体的参数估计
方法是对模型两侧得取对数,从而转化为线性回归模型的形式: .. math:: \ln(q_{ij}) = {
\ln(\alpha) + \beta \ln(Oi \cdot Dj) - {
\gamma \ln(c_{ij})}} 令上式中各个参数项: - :math:`y = \ln(q_{ij})`
- :math:`a_0 = \ln(\alpha)`
- :math:`a_1 = \beta`
- :math:`a_2 = -\gamma` 则可对应如下的线性回归模型: .. math:: Y = a_0 + a_1 x_1 + a_2 x_2 通过对线性模型进行求解和参数的转换,可以实现无约束重力模型的
参数估计。其中,线性模型的求解依赖 `statsmodels.api.OLS`
,您有必要安装 `statsmodels`。 使用下面的命令安装 `statsmodels`: .. code-block:: shell pip install statsmodels 输入参数
----------
X : numpy.array
交通原始的 OD 矩阵,要求行列数相等
C : numpy.array
交通现状下各个交通小区之间往返所需的行驶时间,是交通
距离的量化,要求行列数相等 类的方法
----------
__init__(X, C) :
类的初始化方法
fit() :
拟合模型
OLS_summary() :
输出一元线性回归模型的详细信息
predict(U, V, fC):
预测未来年的交通 OD 矩阵,将直接输出 OD 矩阵 示例
----------
假设已经存在 3*3 的 OD 矩阵 `X` 和 代表各个交通小区之间往返
所需的行驶时间的矩阵 `C`,可以创建模型: >>> X = np.array([[17,7,4],[7,38,6],[4,5,17]])
>>> C = np.array([[7,17,22],[17,15,23],[22,23,7]])
>>> gravity_model = unconstrained_gravity_model(X, C) 使用 `.fit()` 方法可以拟合模型,直接返回的元组即模型的三
参数:math:`\alpha`、:math:`\beta`、:math:`\gamma`,
逐一对应。 >>> gravity_model.fit()
(0.12445664474836608,
1.1726892457872755,
1.4553127410580864) 如果需要模型根据当前年的交通现状预测未来年的交通分布,则需要
未来年各个交通小区的交通发生量 `U`、吸引量 `V`,以及未来年
各个交通小区之间往返所需的行驶时间的矩阵 `fC` >>> fC = np.array([[4,9,11],[9,8,12],[11,12,4]])
>>> U = np.array([38.6, 91.9, 36.0])
>>> V = np.array([39.3, 90.3, 36.9]) 调用 `.predict()` 进行预测 >>> gravity_model.predict(U, V, fC)
array([[ 88.94742489, 72.49109653, 18.95286558],
[ 75.57580647, 237.96479061, 46.18126501],
[ 18.80408686, 43.94860253, 76.12489132]]) 其他参照
----------
:class:`statsmodels.api.OLS`
`statsmodels` 提供的线性回归工具 """ def __init__(self, X, C):
"""
类的初始化方法 输入参数
----------
X : numpy.array, m=n
交通原始的 OD 矩阵
C : numpy.array, m=n
交通现状下各个交通小区之间往返所需的行驶时间
"""
# 将函数参数给到类属性
self.OD_mat = X
self.distance_mat = C # 取得交通小区的个数,交通小区个数即 OD 矩阵长度
self.n = len(self.OD_mat) # 计算总吸引量和总生成量
self.O = np.sum(self.OD_mat, axis=1) # 横向求和
self.D = np.sum(self.OD_mat, axis=0) # 纵向求和 def fit(self):
"""
拟合模型 返回值
-------
tuple
包含重力模型三参数的元组,形如:
`(self.alpha, self.beta, self.gamma)` 示例
------- >>> gravity_model.fit()
(0.12445664474836608,
1.1726892457872755,
1.4553127410580864)
"""
# `x_1` 和 `x_2` 两个列表就能储存取对数后的数值
# 这样的变量命名方式是为了和数学公式里的表述对应以便理解
x_1 = [] # 对 $O_i$ 和 $D_j$ 取对数的结果
x_2 = [] # 对距离矩阵 `distance_mat` 每一项取对数
y = [] # 对原始 OD 矩阵取对数 # 通过循环填充列表
for i in range(self.n):
for j in range(self.n):
y.append(np.log(self.OD_mat[i][j]))
x_1.append(np.log(self.O[i]*self.D[j]))
x_2.append(
np.log(self.distance_mat[i][j])
) # 组织训练线性回归模型的数据
train_X = np.array([x_1, x_2]).T
train_y = y # `statsmodels.api.OLS` 默认没有截距项
# 这里需要手动加入截距
train_X_with_bias = sm.add_constant(train_X)
self.results = sm.OLS( # 注意参数排列的顺序
train_y, train_X_with_bias
).fit() # 直接拟合模型 # 获取线性回归模型参数
self.OLS_params = self.results.params # 根据公式计算模型参数
self.alpha = np.e ** (self.OLS_params[0])
self.beta = self.OLS_params[1]
self.gamma = -self.OLS_params[2] self.params = (self.alpha, self.beta, self.gamma) return self.params def predict(self, U, V, fC):
"""
利用拟合好的模型,根据当前年的交通现状预测未来年的交通分布 输入参数
----------
U : numpy.array
未来年各交通小区的总生成量,行向量
V : numpy.array
未来年各交通小区的总吸引量,行向量
fC : numpy.array
各个交通小区之间往返所需的行驶时间 返回值
-------
numpy.array
预测的未来年各交通小区交通量 示例
-------
如果需要模型根据当前年的交通现状预测未来年的交通分布,则需要
未来年各个交通小区的交通发生量 `U`、吸引量 `V`,以及未来年
各个交通小区之间往返所需的行驶时间的矩阵 `fC` >>> fC = np.array([[4,9,11],[9,8,12],[11,12,4]])
>>> U = np.array([38.6, 91.9, 36.0])
>>> V = np.array([39.3, 90.3, 36.9]) 调用 `.predict()` 进行预测 >>> gravity_model.predict(U, V, fC)
array([[ 88.94742489, 72.49109653, 18.95286558],
[ 75.57580647, 237.96479061, 46.18126501],
[ 18.80408686, 43.94860253, 76.12489132]]) """
self.future_O = U
self.future_D = V
self.future_distance_mat = fC self.q = np.zeros(self.OD_mat.shape) # 根据公式计算 q_ij
for i in range(self.n):
for j in range(self.n):
self.q[i][j] = (
self.alpha * (
((self.future_O[i] * self.future_D[j]) ** self.beta
) / (
self.future_distance_mat[i][j] ** self.gamma
))) return self.q

交通规划四阶段法:基于 Python 的交通分布预测算法复现 - 附完整代码链接的更多相关文章

  1. Python——EM(期望极大算法)教学(附详细代码与注解)

    今天,我们详细的讲一下EM算法. 前提准备 Jupyter notebook 或 Pycharm 火狐浏览器或谷歌浏览器 win7或win10电脑一台 网盘提取csv数据 需求分析 实现高斯混合模型的 ...

  2. 基于Python的函数回归算法验证

    看机器学习看到了回归函数,看了一半看不下去了,看到能用方差进行函数回归,又手痒痒了,自己推公式写代码验证: 常见的最小二乘法是一阶函数回归回归方法就是寻找方差的最小值y = kx + bxi, yiy ...

  3. 基于python的RSA解密算法

    摘要 网上有很多关于RSA的解密脚本,欧拉函数.欧几里得函数什么的,对于一个大专生的我来说,一窍不通,至此经历了三天三夜,我翻阅了RSA的加密原理,以及其底层算法,专研出了一套我自己的解密算法,尚有不 ...

  4. 基于 Python + OpenCV 进行人脸识别,视频追踪代码全注释

    先来普及一下概念, 计算机对人脸是如何识别的呢? 或者说图像是如何识别的.主要是获取单张图片的特征值记录了特征值以后,如果下一张图片来了以后两张图片特征值进行对比,如果相似度很高那么计算机就认定这两个 ...

  5. 基于Python接口自动化测试框架(初级篇)附源码

    引言 很多人都知道,目前市场上很多自动化测试工具,比如:Jmeter,Postman,TestLink等,还有一些自动化测试平台,那为啥还要开发接口自动化测试框架呢?相同之处就不说了,先说一下工具的局 ...

  6. Python反编译调用有道翻译(附完整代码)

         网易有道翻译是一款非常优秀的产品,他们的神经网络翻译真的挺无敌.无奈有道客户端实在是太难用了,而且在某些具体场景 (比如对网站进行批量翻译) 无法使用,而有道的云服务又特别的贵,一般人是无法 ...

  7. python数据处理书pdf版本|内附网盘链接直接提取|

    Python数据处理采用基于项目的方法,介绍用Python完成数据获取.数据清洗.数据探索.数据呈现.数据规模化和自动化的过程.主要内容包括:Python基础知识,如何从CSV.Excel.XML.J ...

  8. Java平台调用Python平台已有算法(附源码及解析)

    1. 问题描述 Java平台要调用Pyhon平台已有的算法,为了减少耦合度,采用Pyhon平台提供Restful 接口,Java平台负责来调用,采用Http+Json格式交互. 2. 解决方案 2.1 ...

  9. 基于Python接口自动化测试框架+数据与代码分离(进阶篇)附源码

    引言 在上一篇<基于Python接口自动化测试框架(初级篇)附源码>讲过了接口自动化测试框架的搭建,最核心的模块功能就是测试数据库初始化,再来看看之前的框架结构: 可以看出testcase ...

  10. 孤荷凌寒自学python第七十四天开始写Python的第一个爬虫4

    孤荷凌寒自学python第七十四天开始写Python的第一个爬虫4 (完整学习过程屏幕记录视频地址在文末) 今天在上一天的基础上继续完成对我的第一个代码程序的书写. 直接上代码.详细过程见文末屏幕录像 ...

随机推荐

  1. WPF 制作一个加密文件夹应用

    我有一个需求就是将我的一些文件夹的内容同步到网盘上面去.但是我是不信任现在的各个网盘的,网盘的数据被我认为是会被泄露的数据,我需要同步的文件夹中,可能存在隐私的数据.于是我就想到了将文件夹里面的内容进 ...

  2. WPF 解决 Skia 因为找不到字体而绘制不出中文字符

    在 WPF 使用 Skia 做渲染工具,如果绘制的中文都是方块,也许是字体的问题.字体的问题是 Skia 没有找到字体,本文告诉大家如何修复 在 Skia 使用特定字体,可以使用 SkiaSharp ...

  3. Linux内核之SPI协议

    SPI(Serial Peripheral Interface,串行外设接口)是一种同步串行的行业标准,但是并没有像I2C那样有标准文档,它还有主从.可片选的特性. 图源自Serial Periphe ...

  4. JAVA也能用上Seq啦

    前言 在.NET生态中,Serilog凭借其强大的结构化日志记录功能和与Seq的无缝集成,已经成为许多开发者的首选日志记录工具.Seq作为一个日志检索和仪表板工具,能够将日志中的插值转换为结构化数据, ...

  5. redo日志全部丢失的情况下。Oracle的实例恢复

    场景: redo日志全部丢失的场景. alert日志报错如下: ORA-00313: 无法打开日志组 1 (用于线程 1) 的成员 ORA-00312: 联机日志 1 线程 1: '/u01/app/ ...

  6. vue子组件给父组件传值

    子组件: <template> <div class="app"> <input @click="sendMsg" type=&q ...

  7. Golang使用正则

    目录 正则在线测试网站 Golang标准库--regexp 相关文章 课程学习地址: 手册地址: dome 正则在线测试网站 https://regex101.com/ Golang标准库--rege ...

  8. Unraid 使用 Docker Compose 安装 Immich 套件无法启用人脸识别的原因及修复方法

    原因 问题原因是官方教程中的 docker-compose.yml 指明的机器学习组件 immich-machine-learning 中的 container_name 与 也就是 docker-c ...

  9. java学习之旅(day.07)

    面向对象编程(oop) 面向过程思想:线性思维 步骤清晰简单,每一步做什么很明确 适合处理较为简单地问题 面向对象思想:总分 抽象 属性+方法=类 分类的思维模式,思考问题首先会解决问题需要哪些分类, ...

  10. 基于 ESP8266_RTOS_SDK 驱动 HC-SR04

    平台 芯片 ESP8266EX 模组 ESP-12F 开发板 NodeMCU SDK ESP8266_RTOS_SDK branch master commit 83517ba1f5e26b9413f ...