# 1.题目

A题 农村公交与异构无人机协同配送优化

# 2.问题1

## 1. 问题建模

A类无人机性能参数：包括最大飞行距离、载重能力、固定费用和飞行费用。

# 3.数据导入

# 公交站点数据
stations_data = pd.DataFrame({
'Station_ID': [1, 2, 3, 4, 5, 6, 7, 8, 9],
'Longitude': [110.125713, 110.08442, 110.029866, 109.962839, 109.956003, 109.920425, 109.839046, 109.823329, 109.767127],
'Latitude': [32.815024, 32.771676, 32.748994, 32.743622, 32.812194, 32.856136, 32.860495, 32.847468, 32.807855]
})
# 需求点数据
demands_data = pd.DataFrame({
'Demand_ID': range(1, 51),
'Longitude': [
110.1053385, 110.1147032, 110.0862574, 110.0435344, 110.0575508,
110.0386243, 110.0115086, 110.0390602, 110.0246454, 110.0575847,
109.9456331, 109.9612274, 109.94592, 109.9316682, 109.9245376,
109.7087533, 109.7748005, 109.7475891, 109.7534532, 109.783015,
109.7410728, 109.7554844, 109.7147417, 109.8807093, 109.8070677,
109.9054481, 109.8954509, 109.8979229, 109.8942179, 109.8610985,
109.8744682, 109.8338804, 109.870924, 109.8292467, 109.8711312,
109.8813363, 109.978788, 109.8166563, 109.8151216, 109.885638,
109.9890984, 109.9647812, 109.9303732, 109.9401099, 109.944496,
109.979708, 109.976757, 109.94999, 109.973673, 109.967765
],
'Latitude': [
32.77881526, 32.75599834, 32.74905239, 32.74275416, 32.76712584,
32.70855831, 32.72619993, 32.73965997, 32.72360718, 32.76553658,
32.7526657, 32.72286471, 32.70899877, 32.73848444, 32.70740885,
32.7815564, 32.80016336, 32.80903496, 32.85129032, 32.82296929,
32.82914197, 32.80581363, 32.79995734, 32.89696579, 32.79622985,
32.89437141, 32.86724756, 32.83444574, 32.83224374, 32.90687042,
32.89939698, 32.85616627, 32.848223, 32.83825122, 32.88979101,
32.8642824, 32.75943454, 32.8096699, 32.82822489, 32.84032485,
32.80854774, 32.80993619, 32.78956582, 32.85264625, 32.802178,
32.817449, 32.811064, 32.795207, 32.746858, 32.820998
],
'Demand_kg': [3, 4, 2, 0, 8, 7, 4, 9, 10, 6, 7, 12, 3, 5, 6, 5, 3, 13, 12, 3,
14, 10, 4, 34, 6, 6, 3, 4, 20, 5, 6, 5, 3, 15, 2, 6, 3, 4, 3, 2,
6, 5, 9, 3, 3, 4, 6, 4, 4, 0]
})
# 无人机参数
D_max = 27  # 最大飞行距离
Q_max = 9   # 最大载重
C_fixed = 80  # 固定费用
C_per_km = 0.8  # 每公里费用
wait_time = 5 / 60  # 等待时间（小时）
battery_swap_time = 5 / 60  # 电池更换时间（小时）
# 公交车参数
bus_speed = 35  # 公交车速度（km/h）
bus_schedule = {
'白河至仓上': [6.67, 8.5, 9, 11, 14, 16.5],
'仓上至白河': [6, 7.33, 8.83, 11, 14, 15.83]
}

# 3.模型构建

import pandas as pd # 公交站点数据 stations_data = pd.DataFrame({ 'Station_ID': [1, 2, 3, 4, 5, 6, 7, 8, 9], 'Longitude': [110.125713, 110.08442, 110.029866, 109.962839, 109.956003, 109.920425, 109.839046, 109.823329, 109.767127], 'Latitude': [32.815024, 32.771676, 32.748994, 32.743622, 32.812194, 32.856136, 32.860495, 32.847468, 32.807855] }) # 需求点数据 demands_data = pd.DataFrame({ 'Demand_ID': range(1, 51), 'Longitude': [ 110.1053385, 110.1147032, 110.0862574, 110.0435344, 110.0575508, 110.0386243, 110.0115086, 110.0390602, 110.0246454, 110.0575847, 109.9456331, 109.9612274, 109.94592, 109.9316682, 109.9245376, 109.7087533, 109.7748005, 109.7475891, 109.7534532, 109.783015, 109.7410728, 109.7554844, 109.7147417, 109.8807093, 109.8070677, 109.9054481, 109.8954509, 109.8979229, 109.8942179, 109.8610985, 109.8744682, 109.8338804, 109.870924, 109.8292467, 109.8711312, 109.8813363, 109.978788, 109.8166563, 109.8151216, 109.885638, 109.9890984, 109.9647812, 109.9303732, 109.9401099, 109.944496, 109.979708, 109.976757, 109.94999, 109.973673, 109.967765 ], 'Latitude': [ 32.77881526, 32.75599834, 32.74905239, 32.74275416, 32.76712584, 32.70855831, 32.72619993, 32.73965997, 32.72360718, 32.76553658, 32.7526657, 32.72286471, 32.70899877, 32.73848444, 32.70740885, 32.7815564, 32.80016336, 32.80903496, 32.85129032, 32.82296929, 32.82914197, 32.80581363, 32.79995734, 32.89696579, 32.79622985, 32.89437141, 32.86724756, 32.83444574, 32.83224374, 32.90687042, 32.89939698, 32.85616627, 32.848223, 32.83825122, 32.88979101, 32.8642824, 32.75943454, 32.8096699, 32.82822489, 32.84032485, 32.80854774, 32.80993619, 32.78956582, 32.85264625, 32.802178, 32.817449, 32.811064, 32.795207, 32.746858, 32.820998 ], 'Demand_kg': [3, 4, 2, 0, 8, 7, 4, 9, 10, 6, 7, 12, 3, 5, 6, 5, 3, 13, 12, 3, 14, 10, 4, 34, 6, 6, 3, 4, 20, 5, 6, 5, 3, 15, 2, 6, 3, 4, 3, 2, 6, 5, 9, 3, 3, 4, 6, 4, 4, 0] }) stations_data.head(), demands_data.head()

(   Station_ID   Longitude   Latitude

0           1  110.125713  32.815024

1           2  110.084420  32.771676

2           3  110.029866  32.748994

3           4  109.962839  32.743622

4           5  109.956003  32.812194,

Demand_ID   Longitude   Latitude  Demand_kg

0          1  110.105339  32.778815          3

1          2  110.114703  32.755998          4

2          3  110.086257  32.749052          2

3          4  110.043534  32.742754          0

4          5  110.057551  32.767126          8)

## 进一步优化

### 具体步骤

import numpy as np
from geopy.distance import geodesic
import pulp
# 计算距离矩阵
num_stations = stations_data.shape[0]
num_demands = demands_data.shape[0]
distances = np.zeros((num_stations, num_demands))
for i, station in stations_data.iterrows():
for j, demand in demands_data.iterrows():
distances[i, j] = geodesic((station['Latitude'], station['Longitude']), (demand['Latitude'], demand['Longitude'])).km
# 无人机参数
D_max = 27  # 最大飞行距离
Q_max = 9   # 最大载重
C_fixed = 80  # 固定费用
C_per_km = 0.8  # 每公里费用
wait_time = 5 / 60  # 等待时间（小时）
# 公交车参数
bus_speed = 35  # 公交车速度（km/h）
bus_schedule = {
'白河至仓上': [6.67, 8.5, 9, 11, 14, 16.5],
'仓上至白河': [6, 7.33, 8.83, 11, 14, 15.83]
}
# 创建优化问题
prob = pulp.LpProblem("Minimize_Cost", pulp.LpMinimize)
# 定义决策变量
x = pulp.LpVariable.dicts("x", (range(num_stations), range(num_demands)), cat='Binary')
t = pulp.LpVariable.dicts("t", (range(num_stations), range(num_demands)), lowBound=0)
# 目标函数
prob += pulp.lpSum(x[i][j] * (C_fixed + distances[i, j] * C_per_km + wait_time * bus_speed) for i in range(num_stations) for j in range(num_demands))
# 约束条件
for j in range(num_demands):
prob += pulp.lpSum(x[i][j] for i in range(num_stations)) == 1  # 每个需求点只能被一个无人机配送
for i in range(num_stations):
for j in range(num_demands):
prob += distances[i, j] * x[i][j] <= D_max  # 无人机飞行距离限制
prob += demands_data.loc[j, 'Demand_kg'] * x[i][j] <= Q_max  # 无人机载重限制
# 公交车行程约束
for schedule in bus_schedule.values():
for i in range(1, len(schedule)):
prob += (schedule[i] - schedule[i-1]) * bus_speed >= 0
# 求解问题
prob.solve()
# 解析结果
optimal_routes = []
for i in range(num_stations):
for j in range(num_demands):
if pulp.value(x[i][j]) == 1:
optimal_routes.append((i+1, j+1, distances[i, j]))
optimal_routes

## 以下是优化模型的具体实现：

### 1.确保所有约束和目标函数都得到正确实现。

import numpy as np
from geopy.distance import geodesic
import pulp
import matplotlib.pyplot as plt
# 计算距离矩阵
num_stations = stations_data.shape[0]
num_demands = demands_data.shape[0]
distances = np.zeros((num_stations, num_demands))
for i, station in stations_data.iterrows():
for j, demand in demands_data.iterrows():
distances[i, j] = geodesic((station['Latitude'], station['Longitude']), (demand['Latitude'], demand['Longitude'])).km
# 无人机参数
D_max = 27  # 最大飞行距离
Q_max = 9   # 最大载重
C_fixed = 80  # 固定费用
C_per_km = 0.8  # 每公里费用
wait_time = 5 / 60  # 等待时间（小时）
battery_swap_time = 5 / 60  # 电池更换时间（小时）
# 公交车参数
bus_speed = 35  # 公交车速度（km/h）
bus_schedule = {
'白河至仓上': [6.67, 8.5, 9, 11, 14, 16.5],
'仓上至白河': [6, 7.33, 8.83, 11, 14, 15.83]
}
# 创建优化问题
prob = pulp.LpProblem("Minimize_Cost", pulp.LpMinimize)
# 定义决策变量
x = pulp.LpVariable.dicts("x", (range(num_stations), range(num_demands)), cat='Binary')
y = pulp.LpVariable.dicts("y", (range(num_stations), range(2)), cat='Binary')  # 每站最多两架无人机
# 目标函数
prob += pulp.lpSum(x[i][j] * (C_fixed + distances[i, j] * C_per_km) + y[i][k] * (wait_time + battery_swap_time) * bus_speed for i in range(num_stations) for j in range(num_demands) for k in range(2))
# 约束条件
for j in range(num_demands):
prob += pulp.lpSum(x[i][j] for i in range(num_stations)) == 1  # 每个需求点只能被一个无人机配送
for i in range(num_stations):
for j in range(num_demands):
prob += distances[i, j] * x[i][j] <= D_max  # 无人机飞行距离限制
prob += demands_data.loc[j, 'Demand_kg'] * x[i][j] <= Q_max  # 无人机载重限制
# 公交车发车和到达时间约束
for schedule in bus_schedule.values():
for i in range(1, len(schedule)):
prob += (schedule[i] - schedule[i-1]) * bus_speed >= 0
# 每站最多两架无人机约束
for i in range(num_stations):
prob += pulp.lpSum(y[i][k] for k in range(2)) <= 2
# 求解问题
prob.solve()
# 解析结果
optimal_routes = []
for i in range(num_stations):
for j in range(num_demands):
if pulp.value(x[i][j]) == 1:
optimal_routes.append((i, j, distances[i, j]))
optimal_routes

### 2. 可视化飞行路径和时间表

# 可视化飞行路径
plt.figure(figsize=(10, 8))
# 绘制公交站点
for i, station in stations_data.iterrows():
plt.plot(station['Longitude'], station['Latitude'], 'bo', markersize=8)
plt.text(station['Longitude'], station['Latitude'], f'S{i+1}', fontsize=12, ha='right')
# 绘制需求点
for j, demand in demands_data.iterrows():
plt.plot(demand['Longitude'], demand['Latitude'], 'ro', markersize=6)
plt.text(demand['Longitude'], demand['Latitude'], f'D{demand["Demand_ID"]}', fontsize=10, ha='left')
# 绘制最优路径
for route in optimal_routes:
station_idx, demand_idx, dist = route
station = stations_data.iloc[station_idx]
demand = demands_data.iloc[demand_idx]
plt.plot([station['Longitude'], demand['Longitude']], [station['Latitude'], demand['Latitude']], 'k--')
plt.xlabel('Longitude')
plt.ylabel('Latitude')
plt.title('Optimal Drone Delivery Routes')
plt.legend(['Bus Station', 'Demand Point'])
plt.grid()
plt.show()
# 输出具体的时间表
schedule_output = []
for route in optimal_routes:
station_idx, demand_idx, dist = route
station = stations_data.iloc[station_idx]
demand = demands_data.iloc[demand_idx]
# 假设从公交站出发的时间为公交车到达时间
for time in bus_schedule['白河至仓上']:
arrival_time = time + dist / bus_speed
schedule_output.append((f'Station {station_idx+1}', f'Demand {demand_idx+1}', time, arrival_time))
schedule_output_df = pd.DataFrame(schedule_output, columns=['Station', 'Demand', 'Departure Time', 'Arrival Time'])
schedule_output_df

|
1月前
|

17 2
|
1月前
|

23 1
|
11月前
|
Java 调度

62 0
|
11月前
|

【VRP问题】基于帝国企鹅优化算法求解冷链配送物流车辆调度优化研究
【VRP问题】基于帝国企鹅优化算法求解冷链配送物流车辆调度优化研究
87 0
|
12月前
|

“蜀道”再升级！车路协同导航服务为司机带来新体验
“蜀道”再升级！车路协同导航服务为司机带来新体验
171 0
|

71 0
|

196 0
|

【多无人机协同】多无人机协同目标运输任务附matlab代码
【多无人机协同】多无人机协同目标运输任务附matlab代码
124 0
|

【VRP问题】基于遗传算法的连锁超市配送路线规划问题研究附matlab代码
【VRP问题】基于遗传算法的连锁超市配送路线规划问题研究附matlab代码
96 0
|

【无人机协同】无人飞行器协同车辆实现物资配送问题附matlab代码
【无人机协同】无人飞行器协同车辆实现物资配送问题附matlab代码
304 0