问题 1:建立线路货量的预测模型,对2023-01-01 至 2023-01-31 期间每条线路每天的货量进行预测,并在提交的论文中给出线路DC14→DC10、 DC20→DC35、DC25→DC62 的预测结果。
这一问比较好上手,主要是预测模型。看到这种问题第一时间要想到,数学建模中常见的预测模型有哪些:
我列个个模型分类,大家看看:
1.线性回归模型:线性回归模型是一种基本的预测模型,用于建立自变量和因变量之间的线性关系。该模型的目标是最小化预测值与实际值之间的误差。
2.非线性回归模型:与线性回归模型不同,非线性回归模型可以建立非线性自变量和因变量之间的关系。这种模型通常用于描述数据中的复杂关系。
3.时间序列模型:时间序列模型是建立时间序列数据之间的关系的一种预测模型。该模型通常用于预测未来的趋势和季节性变化。
4.决策树模型:决策树模型是一种基于树形结构的预测模型,用于识别数据集中的模式和关系,并根据这些关系预测未来的结果。
5.神经网络模型:神经网络模型是一种模仿人脑神经元网络的预测模型,通过对大量数据进行训练来学习数据之间的复杂关系,并用于预测未来的结果。
欢迎关注gz号:数模孵化园!一起交流,获取更多免费思路
根据预测模型的使用场景我们可以判断,这里比较适合时间序列分析方法。这里,我们使用ARIMA(自回归移动平均模型)来进行预测。ARIMA 是一种线性模型,可以捕捉时间序列中的趋势、季节性和噪声成分。接着建立线路货量的预测模型
步骤如下:
1.数据预处理:
首先,将附件 1 中的数据导入到合适的数据结构中,如 pandas 的 DataFrame。然后对数据进行清洗和处理,确保没有缺失值和异常值。为了使用ARIMA 模型,需要将数据按照线路和日期进行重塑,以便得到每条线路的时间序列。
具体步骤:
首先,我们查看附件1中的数据,我把中文数据名字改一下,这样方便导入,名字命名为:d.xlsx,数据格式如下:
场地1 场地2 日期 货量
DC3 DC5 2021-01-01 3
DC3 DC10 2021-01-01 4
DC3 DC14 2021-01-01 4
DC5 DC3 2021-01-01 41
DC5 DC9 2021-01-01 3
DC5 DC10 2021-01-01 140
DC5 DC14 2021-01-01 57
导入到 pandas 的DataFrame中。然后对数据进行清洗和处理,确保没有缺失值和异常值,观察数据可以发现有的数据过大,有的没有,我们需要数据预处理,否则预测有问题。
下面给出代码:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pmdarima import auto_arima
from statsmodels.tsa.arima.model import ARIMA
from sklearn.metrics import mean_squared_error
# 1. 读取数据
data = pd.read_excel("d.xlsx")
# 2. 数据预处理
# 转换日期列为 datetime 类型
data["日期"] = pd.to_datetime(data["日期"])
# 设置日期列为索引
data.set_index("日期", inplace=True)
# 构建线路货量时间序列数据
lines = data.groupby(["场地1", "场地2"])
# 3. 训练和预测
predictions = {}
for line, group in lines:
line_id = f"{line[0]}→{line[1]}"
# 对该线路数据按日期排序
group = group["货量"].sort_index()
# 对数据进行重新采样,按天计算并使用向前填充方法填充缺失值
group = group.resample("D").sum().fillna(method="ffill")
# 检查数据量是否足够
if len(group) < 10:
continue
# 使用 auto_arima 函数自动选择 ARIMA 参数
arima_model = auto_arima(group, seasonal=False, stepwise=True,
suppress_warnings=True, trace=False,
error_action='ignore')
# 拟合 ARIMA 模型
arima_model.fit(group)
# 对 2023-01-01 至 2023-01-31 期间货量进行预测
pred = arima_model.predict(n_periods=31)
# 保存预测结果
date_range = pd.date_range("2023-01-01", "2023-01-31")
predictions[line_id] = pd.Series(pred, index=date_range)
# 输出指定线路的预测结果
specified_lines = ["DC14→DC10", "DC20→DC35", "DC25→DC62"]
for line in specified_lines:
if line in predictions:
print(f"Line {line} prediction:")
print(predictions[line])
print()
else:
print(f"Line {line} has insufficient data for prediction.")
print()
如果要作出图,可以考虑将每条指定线路绘制一条预测货量曲线。图表的x轴表示日期,y轴表示预测货量。线条的颜色和图例分别表示不同线路。
import matplotlib.dates as mdates
# 设置画布大小
plt.figure(figsize=(12, 6))
# 设置日期格式
date_fmt = mdates.DateFormatter('%Y-%m-%d')
# 绘制指定线路的预测结果
for line in specified_lines:
if line in predictions:
plt.plot(predictions[line], label=line)
else:
print(f"Line {line} has insufficient data for prediction.")
# 设置图表标题、坐标轴标签和图例
plt.title("货量预测")
plt.xlabel("日期")
plt.ylabel("预测货量")
plt.legend()
# 设置 x 轴日期格式
ax = plt.gca()
ax.xaxis.set_major_formatter(date_fmt)
# 自动旋转x轴日期,以便阅读
plt.xticks(rotation=45)
# 显示图表
plt.show()
2.差分和平稳性检验:
对每条线路的时间序列数据进行差分,以消除趋势和季节性影响。然后使用 Augmented Dickey-Fuller (ADF) 测试检查数据的平稳性。如果数据不平稳,可以进一步进行差分直至平稳。
import pandas as pd
import numpy as np
from statsmodels.tsa.stattools import adfuller
from statsmodels.tsa.seasonal import seasonal_decompose
# 读取数据
df = pd.read_excel('d.xlsx')
# 将日期列转换为 datetime 类型
df['日期'] = pd.to_datetime(df['日期'])
# 设置日期为索引
df.set_index('日期', inplace=True)
# 用于存储平稳后的线路数据
stationary_data = {}
# 获取唯一的线路
unique_routes = df[['场地1', '场地2']].drop_duplicates().values
# 遍历所有线路
for route in unique_routes:
site1, site2 = route
route_key = f'{site1}→{site2}'
# 获取当前线路的货量数据
route_df = df[(df['场地1'] == site1) & (df['场地2'] == site2)]['货量']
# 差分直至平稳
diff_df = route_df
while True:
result = adfuller(diff_df)
p_value = result[1]
# ADF 检验的 p 值小于 0.05 时,认为数据平稳
if p_value < 0.05:
break
diff_df = diff_df.diff().dropna()
# 存储平稳后的线路数据
stationary_data[route_key] = diff_df
# 示例输出
print(stationary_data['DC3→DC5'])
作用是对每条线路的货量数据进行差分,直到 Augmented Dickey-Fuller (ADF) 检验的 p 值小于 0.05 时认为数据已经平稳。最后,将平稳后的线路数据存储到一个字典中。
3.参数选择:
为了确定 ARIMA 模型的阶数(p, d, q),我们可以使用自相关函数 (ACF) 和偏自相关函数 (PACF) 图来确定 p 和 q 的值。同时,根据前面的差分步骤来确定 d 的值。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from statsmodels.tsa.stattools import adfuller
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
from statsmodels.tsa.arima.model import ARIMA
# 读取数据
data = pd.read_excel('d.xlsx')
# 以场地1、场地2和日期为索引重塑数据
data_pivoted = data.pivot_table(values='货量', index=['场地1', '场地2'], columns='日期')
# 选择感兴趣的线路,例如 DC14→DC10
route = data_pivoted.loc[('DC14', 'DC10')]
# 检查平稳性
result = adfuller(route)
print(f"ADF Statistic: {result[0]}")
print(f"p-value: {result[1]}")
# 如果数据不平稳,则进行差分
if result[1] > 0.05:
diff_route = route.diff().dropna()
result = adfuller(diff_route)
print(f"ADF Statistic after differencing: {result[0]}")
print(f"p-value after differencing: {result[1]}")
# ACF 和 PACF 图
plot_acf(diff_route)
plot_pacf(diff_route)
plt.show()
# 根据 ACF 和 PACF 图选择 p 和 q 值
p, q = 1, 1
d = 1 # 差分步骤
# 拟合 ARIMA 模型
model = ARIMA(route, order=(p, d, q))
model_fit = model.fit()
# 预测 2023-01-01 至 2023-01-31 的货量
forecast = model_fit.forecast(steps=31)
print(forecast)
4.模型拟合和评估:
使用确定的 p, d, q 参数值拟合 ARIMA 模型。为了评估模型的性能,我们可以使用均方误差(MSE)或者其他误差指标。如果需要,可以进一步调整参数以优化模型表现。
import pandas as pd
import numpy as np
from statsmodels.tsa.arima.model import ARIMA
from sklearn.metrics import mean_squared_error
# 假设已经完成数据预处理并确定了 p, d, q 参数值
# route 是需要预测的线路的时间序列数据
# 将数据分为训练集和测试集
train_data = route[:'2021-12-01']
test_data = route['2021-12-02':]
# 拟合 ARIMA 模型
model = ARIMA(train_data, order=(p, d, q))
model_fit = model.fit()
# 预测测试集
forecast = model_fit.forecast(steps=len(test_data))
# 计算 MSE
mse = mean_squared_error(test_data, forecast)
print("Mean Squared Error:", mse)
5.预测:
使用拟合的 ARIMA 模型对 2023-01-01 至 2023-01-31 期间每条线路的货量进行预测。特别地,对线路 DC14→DC10、DC20→DC35 和 DC25→DC62 的预测结果进行展示。
import pandas as pd
import numpy as np
from statsmodels.tsa.arima.model import ARIMA
# 假设已经完成数据预处理并确定了 p, d, q 参数值
# data_pivoted 是已经按照场地1、场地2和日期重塑的数据
# 需要预测的线路
routes = [('DC14', 'DC10'), ('DC20', 'DC35'), ('DC25', 'DC62')]
# 为每条线路拟合 ARIMA 模型并进行预测
for route in routes:
print(f"Predicting for route {route[0]}→{route[1]}")
# 提取线路的时间序列数据
route_data = data_pivoted.loc[route]
# 拟合 ARIMA 模型
model = ARIMA(route_data, order=(p, d, q))
model_fit = model.fit()
# 预测 2023-01-01 至 2023-01-31 的货量
forecast = model_fit.forecast(steps=31)
# 输出预测结果
print(forecast)
print("\n")
问题 2:如果物流场地 DC5 于 2023-01-01 开始关停,请在问题 1 的预测基础上,建立数学模型,将 DC5 相关线路的货量分配到其他线路使所有包裹尽可能正常流转,并使得 DC5 关停前后货量发生变化的线路尽可能少,且保持各条线路的工作负荷尽可能均衡。如果存在部分日期部分货量没有正常流转,你们的分流方案还应使得 2023-01-01 至 2023-01-31 期间未能正常流转的包裹日累计总量尽可能少。正常流转时,请给出因 DC5 关停导致货量发生变化的线路数及网络负荷情况;不能正常流转时,请给出因DC5关停导致货量发生变化的线路数、不能正常流转的货量及网络的负荷情况。
这题很明显是一个线性规划模型。怎么分析?需要约束条件,需要决策变量,需要最优值。
首先,基于问题1中的预测模型,获取 2023-01-01 至 2023-01-31 期间每条线路每天的预测货量,上面建立了,预测这个不难。
接着就是识别受 DC5 关停影响的线路。这包括所有以 DC5 为始发地或目的地的线路。
这里有个小步骤:从问题 1 的预测结果中提取线路及其货量数据。假设该数据存储在名为 predicted_data 的 Pandas DataFrame 中,具有 "场地1", "场地2", "日期" 和 "货量" 列。再使用 Pandas 的筛选功能,找到所有以 DC5 为始发地或目的地的线路。
import pandas as pd
# 从预测数据中筛选受 DC5 关停影响的线路
affected_routes = predicted_data[(predicted_data["场地1"] == "DC5") | (predicted_data["场地2"] == "DC5")]
# 输出受影响的线路
print(affected_routes)
为每条受影响的线路找到候选替代线路。候选线路应避免包含 DC5,并确保始发地和目的地之间的距离尽可能短。为了找到候选替代线路,我们需要考虑避免包含 DC5 的线路,同时确保始发地和目的地之间的距离尽可能短。这里我们假设有一个名为 distances 的 DataFrame,其中包含所有物流场地之间的距离信息,具有 "场地1", "场地2" 和 "距离" 列。
以下是为每条受影响的线路找到候选替代线路的具体步骤
import pandas as pd
# 以下为示例数据
# affected_routes: 受影响的线路
# distances: 所有物流场地之间的距离信息
alternative_routes = {}
for index, row in affected_routes.iterrows():
origin = row["场地1"]
destination = row["场地2"]
# 从距离数据中找到不包含 DC5 的线路
candidate_routes = distances[((distances["场地1"] != "DC5") & (distances["场地2"] != "DC5")) &
(((distances["场地1"] == origin) & (distances["场地2"] == destination)) |
((distances["场地1"] == destination) & (distances["场地2"] == origin)))]
# 按距离排序并选择前 N 个最短距离的线路作为候选替代线路
N = 3
candidate_routes = candidate_routes.sort_values("距离").head(N)
# 将找到的候选替代线路添加到 alternative_routes 字典中
alternative_routes[(origin, destination)] = candidate_routes[["场地1", "场地2"]].values.tolist()
# 输出候选替代线路
print(alternative_routes)
简单来说就是考虑避免包含 DC5 的线路,同时确保始发地和目的地之间的距离尽可能短。
再遍历受影响的线路列表(从第二步中获取),并为每条线路找到一个或多个候选替代线路。
使用 distances DataFrame,找到避免 DC5 的线路,并确保始发地和目的地之间的距离尽可能短。
将找到的候选替代线路存储在一个名为 alternative_routes 的字典中,其中键为受影响的线路,值为候选替代线路列表。
使用线性规划方法为每条受影响的线路分配货量。线性规划模型的目标是最小化未能正常流转的包裹数量、受影响线路数量和各线路工作负荷的不均衡程度。
注意,这里需要遵循以下约束条件:
每条线路的货量不能超过其历史最大货量(作为运输能力上限)。
每个物流场地的处理能力不能超过其历史最大处理能力。
尽量减少未能正常流转的包裹数量。
使用求解器(例如Python的SciPy库或CVXPY库)求解线性规划问题(这里有很多求解方法,网上很多,多试试),获取货量分配方案。
根据分配方案,计算受影响的线路数量、未能正常流转的包裹数量和网络负荷情况。
第三问:
问题 3:在问题 2 中,如果被关停的物流场地为 DC9,同时允许对物流网络结构进行动态调整(每日均可调整),调整措施为关闭或新开线路,不包含新增物流场地,假设新开线路的运输能力的上限为已有线路运输能力的最大值。请将 DC9 相关线路的货量分配到其他线路,使所有包裹尽可能正常流转,并使得 DC9 关停前后货量发生变化的线路数尽可能少,且保持各条线路的工作负荷尽可能均衡。如果存在部分日期没有满足要求的流转方案,你们的分流方案还应使得 2023-01-01 至 2023-01-31 期间未能正常流转的包裹日累计总量尽可能少。正常流转时,请给出因 DC9 关停导致货量发生变化的线路数及网络负荷情况;不能正常流转时,请给出因 DC9关停导致货量发生变化的线路数、不能正常流转的货量及网络的负荷情况;同时请给出每天的线路增减情况。
根据问题1中的预测结果,获取2023-01-01至2023-01-31期间每条线路每天的预测货量。
找到与DC9相关的线路(即,始发地或目的地为DC9的线路)。遍历日期范围(2023-01-01至2023-01-31),针对每一天,按照以下步骤执行:
a. 找到当前日期的受影响线路及其预测货量。
b. 识别候选替代线路,这些线路应避免包含DC9,并确保始发地和目的地之间的距离尽可能短。同时,允许新开线路,但运输能力上限为已有线路运输能力的最大值。
c. 使用线性规划方法为每条受影响的线路分配货量。目标是最小化未能正常流转的包裹数量、受影响线路数量和各线路工作负荷的不均衡程度。同时,需要满足线路运输能力限制和物流场地处理能力限制。
d. 根据线性规划问题的解决方案,确定当前日期的货量分配方案。同时,记录因DC9关停导致货量发生变化的线路数、不能正常流转的货量及网络负荷情况。此外,记录每天的线路增减情况。
输出整个日期范围内的货量分配方案、受影响的线路数量、未能正常流转的货量、网络负荷情况以及每天的线路增减情况。
问题 4:根据附件 1,请对该网络的不同物流场地及线路的重要性进行 评价;为了改善网络性能,如果打算新增物流场地及线路,结合问题 1 的 预测结果,探讨分析新增物流场地应与哪几个已有物流场地之间新增线路,新增物流场地的处理能力及新增线路的运输能力应如何设置?考虑到预测结果的随机性,请进一步探讨你们所建网络的鲁棒性。
先评价现有物流场地和线路的重要性。这可以通过计算各物流场地和线路的流量、处理包裹数量、货物运输时间等指标来实现。
再分析问题1的预测结果,找出可能出现瓶颈的物流场地和线路,即货量高、运输能力受限或处理能力不足的场地和线路。
在现有网络中寻找合适的位置添加新物流场地。这可以通过以下方法实现:
a. 找出邻近物流场地之间距离较大的区域,以减少运输时间和成本。
b. 找出预测结果中可能出现瓶颈的物流场地,以提高处理能力和运输能力。
c. 综合考虑地理位置、运输成本、设施成本等因素,确定最佳位置。
根据新增物流场地的位置,确定与现有物流场地之间新增线路。可以使用最短路径算法(如Dijkstra算法)在现有物流网络中找到最短路线。
为新增物流场地设置处理能力和新增线路设置运输能力。可以根据预测结果和现有物流场地及线路的最大处理能力和运输能力来设置。同时,可以考虑将新增物流场地的处理能力设置为高于预测货量的某一百分比,以增加鲁棒性。
为了评估新网络的鲁棒性,可以对预测结果进行敏感性分析。这包括在预测货量上添加随机波动,并观察网络性能如何受到影响。如果网络在多种情况下都能保持良好的性能,那么可以认为网络具有较好的鲁棒性。
怕有的小伙伴不懂,这里给出具体步骤:
对预测货量进行敏感性分析:在原有预测货量的基础上,添加不同程度的随机波动。例如,可以为预测货量添加±5%、±10%和±15%的波动。这样可以生成一系列不同的货量情景,以评估网络在不同情况下的性能。
再使用不同货量情景评估网络性能:针对每个货量情景,运行网络模拟,并计算关键性能指标,如运输时间、处理时间、包裹延误数量等。可以使用现有的物流模拟软件或自行编写程序来进行模拟。
接着就是比较不同情景下的性能指标:对于每个关键性能指标,比较不同货量情景下的结果。评估指标的波动程度,以了解网络在不同情况下的稳定性和鲁棒性。
最后评价网络鲁棒性:根据性能指标的波动程度和网络在不同情景下的表现,评价网络的鲁棒性。如果在大多数情况下,网络性能仍然可以维持在一个可接受的水平,那么可以认为网络具有较好的鲁棒性。
欢迎交流!gzh:数模孵化园
其他题目免费思路可关注gzh找到作者。