交通规划四阶段法:基于 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. STM32中的看门狗

    先复制一段度娘的东西: 在由单片机构成的微型计算机系统中,由于单片机的工作常常会受到来自外界电磁场的干扰,造成程序的跑飞,而陷入死循环,程序的正常运行被打断,由单片机控制的系统无法继续工作,会造成整个 ...

  2. 记录Notion API Authorization中的一个坑

    正文 Notion官方文档的Authorization部分提到: In your integration code, include the token in the Authorization he ...

  3. apisix~jwt-auth插件

    在网关开启jwt-auth插件之后,你的网关就具有了jwt解析和校验的功能,主要是校验jwt token的有效性,包含过期时间和签名等. https://apisix.apache.org/docs/ ...

  4. ctf_web

    ctfshow web13 访问题目链接 一看是一道文件上传题,上传文件进行测试 上传php会显示 error suffix 因此推测会检测格式 当文件字数超出一定字数时,显示 error file ...

  5. NumPy 数组迭代与合并详解

    NumPy 数组迭代 NumPy 数组迭代是访问和处理数组元素的重要方法.它允许您逐个或成组地遍历数组元素. 基本迭代 我们可以使用 Python 的基本 for 循环来迭代 NumPy 数组. 一维 ...

  6. C 语言编程 — 高级数据类型 — 数组

    目录 文章目录 目录 前文列表 数组 声明数组 初始化数据 访问数组元素 二维数组 指向数组的指针 将数组指针作为实参传入函数 从函数返回一个数组指针 指针数组 数组名和取数组首地址的区别 前文列表 ...

  7. 通过 OpenAPI 部署 Nbsf_Management API Service

    目录 文章目录 目录 准备 部署 启动 API 服务 调用 准备 GentOS7 Golang1.12.5 Swagger YAML TS29521_Nbsf_Management.yaml TS29 ...

  8. winform 使用Clipboard 和windows Word Com组件 把Html 导出到word

    首先是把Html复制到剪贴板 见:https://www.cnblogs.com/HelloQLQ/p/16289343.html 然后使用: private void saveAsWordCopy( ...

  9. EL表达式与JSTL简单入门

    更多博文请关注:听到微笑的博客 EL概述 EL(Express Lanuage)表达式可以嵌入在jsp页面内部,减少jsp脚本的编写,EL出现的目的是要替代jsp页面中脚本的编写. 简单来说EL表达式 ...

  10. 七年之痒!一个 PHP 程序员职业生涯的自述

    大家好,我是码农先森. 今年刚好是我毕业的第七个年头,在婚姻感情当中都有一种「七年之痒」的说法,这次我把这个词「七年之痒」用一次在我的职业生涯复盘上.七年前我从告别校园,踏入互联网编程行业,七年后我依 ...