2025五一杯数学建模竞赛A题 交通流量推测 保姆级教程讲解|模型讲解

完整内容看文章最后的推广群

2025五一杯数学建模竞赛(五一赛)A题保姆级分析完整思路+代码+数据教学

DS数模-五一数学建模竞赛 A题保姆级教程思路分析

下面我将以背景介绍、数据集分析、问题分析的步骤来给大家讲解A题的具体思路。

1 背景介绍

该题目属于交通流量推测与建模问题,核心目标是通过主路监测数据反推未安装监测设备的支路车流量。主路车流量是各支路流量的总和,结合历史规律(如线性增长、周期性变化等),建立数学模型描述支路流量随时间的变化规律。其应用价值在于优化交通信号灯配时、缓解拥堵和道路资源规划。

共包含5个子问题,涉及不同道路拓扑(Y型、多支路交汇、信号灯控制等)和复杂条件(时间延迟、信号灯周期、数据误差)。各问题的核心差异如下:

  • 问题1​:简单Y型道路,两支路流量分别呈单一段线性增长和分段线性变化。
  • 问题2​:多支路交汇,需考虑支路到达监测点的行驶时间差异及周期性流量。
  • 问题3-4​:引入交通信号灯控制,支路流量受红灯/绿灯周期性影响,且需处理数据误差。
  • 问题5​:确定监测设备的最少记录时刻,以推断支路流量函数。
    这道题目的核心难点是:
  • 多变量解耦​:主路数据为各支路流量叠加,需通过约束条件和历史规律分离变量。
  • 时间延迟建模​:车辆行驶到监测点的时间差需在模型中体现(如问题2支路1、2的2分钟延迟)。
  • 周期性函数拟合​:问题2支路4的周期性流量需选择合适的周期函数(如三角函数)。
  • 信号灯同步性​:确定绿灯开始时刻(如问题3中首个绿灯为7:06)并分段建模。

给大家提示一下几个方法:1 分段建模​:对具有不同趋势的时间段分别定义函数,确保分段点连续。2 约束优化​:利用主路流量=支路流量之和的约束,构建方程组求解参数。3 参数拟合方法​:最小二乘法、非线性回归或傅里叶变换(周期性支路)。4 误差分析​:通过残差计算或交叉验证评估模型可靠性。

2 数据集分析

以下为各附件核心字段说明及数据特性:

所有表格包含以下字段:

  • 时刻 (Moment)​: 时间戳(格式 HH:MM)
  • 时间 t (Time t)​: 以分钟为单位的连续时间索引(0~59)
  • 车流量: 不同主路的车流量数值(单位未明确,假设为辆/分钟)

​数据特征分析​

  1. 表1-主路3​:车流量随时间线性增长,08:00后出现下降。
  2. 表2-主路5​:数值精度不一致(如35.700000000000003),存在突变点(如07:36的71.3)。
  3. 表3-主路4​:数值波动剧烈(如07:08的34.6到07:10的37.3)。
  4. 表4-主路4​:数据分布与表3不同,可能为不同传感器数据。

数据预处理过程:

1 缺失值检查​:验证时间连续性2 数值精度统一​:保留2位小数3 异常值检测​:基于标准差或分位数 4 时间格式转换​:将时刻转为datetime对象

import pandas as pd

import numpy as np

def preprocess_table(sheet_name):

# 读取数据

df = pd.read_excel("Attachment.xlsx", sheet_name=sheet_name)

# 1. 数据清洗

df = df.round(2) # 统一精度

df = df.drop_duplicates(subset=["时间 t (Time t)"]) # 去重

# 2. 缺失值处理

expected_t = range(60)

missing_t = list(set(expected_t) - set(df["时间 t (Time t)"]))

if missing_t:

print(f"缺失时间点:{missing_t}")

# 线性插值填充(可选)

df = df.set_index("时间 t (Time t)").reindex(expected_t).interpolate().reset_index()

# 3. 异常值检测

flow_col = df.columns[-1]

mean = df[flow_col].mean()

std = df[flow_col].std()

outliers = df[np.abs(df[flow_col] - mean) > 3*std]

if not outliers.empty:

print(f"异常值:\n{outliers}")

# 4. 时间格式转换

df["时刻 (Moment)"] = pd.to_datetime(df["时刻 (Moment)"], format="%H:%M")

return df

# 处理所有表格

tables = {

"Table1": "主路3的车流量",

"Table2": "主路5的车流量", 

"Table3": "主路4的车流量",

"Table4": "主路4的车流量"

}

processed_data = {}

for sheet, col in tables.items():

df = preprocess_table(sheet)

processed_data[sheet] = df

print(f"\n{sheet}预处理完成,示例如下:")

print(df.head(3))

输出验证:

# 检查数据分布

for name, df in processed_data.items():

print(f"\n{name}统计描述:")

print(df.describe())

# 保存预处理结果

with pd.ExcelWriter("Processed_Data.xlsx") as writer:

for name, df in processed_data.items():

df.to_excel(writer, sheet_name=name, index=False)

以下是针对交通流量数据集的可视化方法及Python代码实现,涵盖趋势分析、异常检测和多路对比:

时间序列折线图来观察流量变化趋势

import matplotlib.pyplot as plt

def plot_timeseries(df, road_name):

plt.figure(figsize=(15, 5))

plt.plot(df["时间 t (Time t)"], df.iloc[:, -1], 

marker='o', linestyle='--', linewidth=1)

plt.title(f"{road_name} Traffic Flow")

plt.xlabel("Time t (minutes)")

plt.ylabel("Vehicles/min")

plt.grid(alpha=0.4)

plt.xticks(range(0, 60, 5))

plt.show()

# 示例使用

plot_timeseries(processed_data["Table1"], "Main Road 3")

​箱线图来检测异常值分布)​

import seaborn as sns

def plot_boxplot(df_list, road_names):

flows = [df.iloc[:, -1] for df in df_list]

plt.figure(figsize=(10, 5))

sns.boxplot(data=flows, palette="Set2")

plt.xticks(range(len(road_names)), road_names)

plt.title("Traffic Flow Distribution Comparison")

plt.ylabel("Vehicles/min")

plt.show()

# 示例使用

plot_boxplot([processed_data["Table1"], 

processed_data["Table2"]],

["Road3", "Road5"])

3 问题分析

问题一分析与求解:

时间特性:

时间相关性​:流量数据具有强时间依赖性(前序时刻影响后续时刻)

​多路耦合​:不同主路流量可能存在相互影响(如相邻道路拥堵导致分流)

​突变特征​:部分时段出现流量骤变(如交通事故、信号灯变化)

模型:

代码:

# 环境准备

import pandas as pd

import numpy as np

from sklearn.model_selection import TimeSeriesSplit

from statsmodels.tsa.arima.model import ARIMA

from xgboost import XGBRegressor

import tensorflow as tf

# 数据加载

def load_data(path):

df = pd.read_excel(path, parse_dates=['时刻 (Moment)'])

df.set_index('时刻 (Moment)', inplace=True)

return df['主路3的车流量 (Traffic flow on the Main road 3)']

# 特征工程

def create_features(series, lags=6):

df = pd.DataFrame(series)

for i in range(1, lags+1):

df[f'lag_{i}'] = series.shift(i)

df['hour'] = df.index.hour

df['day_part'] = np.where(df['hour'] < 12, 0, 1)

return df.dropna()

# 模型训练

def train_models(X_train, y_train):

# ARIMA

arima = ARIMA(y_train, order=(2,1,1))

arima_model = arima.fit()

# XGBoost

xgb = XGBRegressor(objective='reg:squarederror')

xgb.fit(X_train[['lag_1', 'hour']], y_train)

# LSTM

lstm = tf.keras.Sequential([

tf.keras.layers.LSTM(50, input_shape=(X_train.shape[1], 1)),

tf.keras.layers.Dense(1)

])

lstm.compile(loss='mae', optimizer='adam')

X_3d = X_train.values.reshape((X_train.shape[0], X_train.shape[1], 1))

lstm.fit(X_3d, y_train, epochs=30, verbose=0)

return arima_model, xgb, lstm

# 主流程

if __name__ == "__main__":

# 数据准备

data = load_data("Processed_Data.xlsx")

processed_df = create_features(data)

# 划分训练测试集

split = int(len(processed_df)*0.8)

train, test = processed_df.iloc[:split], processed_df.iloc[split:]

# 模型训练

arima, xgb, lstm = train_models(train.drop(columns=['value']), train['value'])

# 模型保存

arima.save('arima_model.pkl')

xgb.save_model('xgb_model.json')

lstm.save('lstm_model.h5')

其中更详细的思路、各题目思路、代码、讲解视频、成品论文及其他相关内容,可以点击下方名片获取:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值