修改算法的输出,把可视化模块单独分离出来
This commit is contained in:
parent
b1851ac489
commit
1f18d9d96f
1
.gitignore
vendored
1
.gitignore
vendored
@ -9,6 +9,7 @@ __pycache__/
|
||||
|
||||
# Pytorch weights
|
||||
weights/
|
||||
solutions/
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
|
161
mtkl_sovler.py
161
mtkl_sovler.py
@ -1,8 +1,8 @@
|
||||
import random
|
||||
import math
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib.patches as patches
|
||||
import yaml
|
||||
import json
|
||||
|
||||
# 固定随机种子,便于复现
|
||||
random.seed(42)
|
||||
|
||||
@ -18,7 +18,6 @@ H = params['H']
|
||||
W = params['W']
|
||||
k = params['num_cars']
|
||||
|
||||
|
||||
flight_time_factor = params['flight_time_factor']
|
||||
comp_time_factor = params['comp_time_factor']
|
||||
trans_time_factor = params['trans_time_factor']
|
||||
@ -117,7 +116,7 @@ for iteration in range(num_iterations):
|
||||
total_flight_time = sum(task['flight_time'] for task in tasks)
|
||||
if tasks:
|
||||
# 车辆从区域中心到第一个任务中心
|
||||
car_time += math.dist(tasks[0]['center'], region_center) * car_time_factor
|
||||
car_time = math.dist(tasks[0]['center'], region_center) * car_time_factor
|
||||
# 依次经过任务中心
|
||||
for j in range(len(tasks) - 1):
|
||||
prev_center = tasks[j]['center']
|
||||
@ -159,131 +158,37 @@ for iteration in range(num_iterations):
|
||||
if best_solution is not None:
|
||||
print("最佳 T (各系统中最长的完成时间):", best_solution['T_max'])
|
||||
print(best_solution['iteration'], "次模拟后找到最佳方案:")
|
||||
print(best_solution['car_time'], best_solution['flight_time'], best_solution['bs_time'])
|
||||
print("分区情况:")
|
||||
print("行分段数:", best_solution['R'])
|
||||
print("列分段数:", best_solution['C'])
|
||||
print("行分割边界:", best_solution['row_boundaries'])
|
||||
print("列分割边界:", best_solution['col_boundaries'])
|
||||
print("每辆车的运行轨迹情况:")
|
||||
car_paths = {}
|
||||
for i in range(k):
|
||||
num_tasks = len(best_solution['system_tasks'][i])
|
||||
print(
|
||||
f"系统 {i}: 完成时间 T = {best_solution['T_k_list'][i]}, 飞行任务数量: {num_tasks}")
|
||||
print(f"系统 {i}: 完成时间 T = {best_solution['T_k_list'][i]}, 飞行任务数量: {num_tasks}")
|
||||
tasks = best_solution['system_tasks'][i]
|
||||
tasks.sort(key=lambda r: math.hypot(r['center'][0] - region_center[0],
|
||||
r['center'][1] - region_center[1]))
|
||||
if tasks:
|
||||
print(f"轨迹路线: 区域中心({region_center[0]:.1f}, {region_center[1]:.1f})", end="")
|
||||
current_pos = region_center
|
||||
car_path = []
|
||||
for j, task in enumerate(tasks, 1):
|
||||
current_pos = task['center']
|
||||
car_path.append(current_pos)
|
||||
print(f" -> 任务{j}({current_pos[0]:.1f}, {current_pos[1]:.1f})", end="")
|
||||
print(" -> 区域中心")
|
||||
car_paths[i] = car_path
|
||||
|
||||
# 保存分区边界和车辆轨迹到JSON文件
|
||||
output_data = {
|
||||
'row_boundaries': [boundary / H for boundary in best_solution['row_boundaries']],
|
||||
'col_boundaries': [boundary / W for boundary in best_solution['col_boundaries']],
|
||||
'car_paths': car_paths
|
||||
}
|
||||
with open('./solutions/best_solution_mtkl.json', 'w', encoding='utf-8') as f:
|
||||
json.dump(output_data, f, ensure_ascii=False, indent=4)
|
||||
else:
|
||||
print("在给定的模拟次数内未找到满足所有约束的方案。")
|
||||
|
||||
# 在输出最佳方案后添加详细信息
|
||||
if best_solution is not None:
|
||||
print("\n各系统详细信息:")
|
||||
region_center = (W / 2.0, H / 2.0)
|
||||
|
||||
for system_id, tasks in best_solution['system_tasks'].items():
|
||||
print(f"\n系统 {system_id} 的任务详情:")
|
||||
|
||||
# 按距离区域中心的距离排序任务
|
||||
tasks_sorted = sorted(tasks, key=lambda r: math.hypot(r['center'][0] - region_center[0],
|
||||
r['center'][1] - region_center[1]))
|
||||
|
||||
if tasks_sorted:
|
||||
print(
|
||||
f"轨迹路线: 区域中心({region_center[0]:.1f}, {region_center[1]:.1f})", end="")
|
||||
current_pos = region_center
|
||||
total_car_time = 0
|
||||
total_flight_time = 0
|
||||
total_flight_energy = 0
|
||||
total_comp_energy = 0
|
||||
total_trans_energy = 0
|
||||
|
||||
for i, task in enumerate(tasks_sorted, 1):
|
||||
# 计算车辆移动时间
|
||||
car_time = math.hypot(task['center'][0] - current_pos[0],
|
||||
task['center'][1] - current_pos[1]) * car_time_factor
|
||||
total_car_time += car_time
|
||||
|
||||
# 更新当前位置
|
||||
current_pos = task['center']
|
||||
print(
|
||||
f" -> 任务{i}({current_pos[0]:.1f}, {current_pos[1]:.1f})", end="")
|
||||
|
||||
# 累加各项数据
|
||||
total_flight_time += task['flight_time']
|
||||
total_flight_energy += flight_energy_factor * task['d']
|
||||
total_comp_energy += comp_energy_factor * \
|
||||
task['rho'] * task['d']
|
||||
total_trans_energy += trans_energy_factor * \
|
||||
(1 - task['rho']) * task['d']
|
||||
|
||||
print("\n")
|
||||
print(f"任务数量: {len(tasks_sorted)}")
|
||||
print(f"车辆总移动时间: {total_car_time:.2f} 秒")
|
||||
print(f"无人机总飞行时间: {total_flight_time:.2f} 秒")
|
||||
print(f"能耗统计:")
|
||||
print(f" - 飞行能耗: {total_flight_energy:.2f} 分钟")
|
||||
print(f" - 计算能耗: {total_comp_energy:.2f} 分钟")
|
||||
print(f" - 传输能耗: {total_trans_energy:.2f} 分钟")
|
||||
print(
|
||||
f" - 总能耗: {(total_flight_energy + total_comp_energy + total_trans_energy):.2f} 分钟")
|
||||
|
||||
print("\n各任务详细信息:")
|
||||
for i, task in enumerate(tasks_sorted, 1):
|
||||
print(f"\n任务{i}:")
|
||||
print(
|
||||
f" 位置: ({task['center'][0]:.1f}, {task['center'][1]:.1f})")
|
||||
print(f" 照片数量: {task['d']}")
|
||||
print(f" 卸载比率(ρ): {task['rho']:.2f}")
|
||||
print(f" 飞行时间: {task['flight_time']:.2f} 秒")
|
||||
print(f" 计算时间: {task['comp_time']:.2f} 秒")
|
||||
print(f" 传输时间: {task['trans_time']:.2f} 秒")
|
||||
print(f" -- 飞行能耗: {task['d'] * flight_energy_factor:.2f} 分钟")
|
||||
print(f" -- 计算能耗: {task['d'] * comp_energy_factor:.2f} 分钟")
|
||||
print(f" -- 传输能耗: {task['d'] * trans_energy_factor:.2f} 分钟")
|
||||
print(f" 基站计算时间: {task['bs_time']:.2f} 秒")
|
||||
else:
|
||||
print("该系统没有分配任务")
|
||||
print("-" * 50)
|
||||
|
||||
if best_solution is not None:
|
||||
plt.rcParams['font.family'] = ['sans-serif']
|
||||
plt.rcParams['font.sans-serif'] = ['SimHei']
|
||||
fig, ax = plt.subplots()
|
||||
ax.set_xlim(0, W)
|
||||
ax.set_ylim(0, H)
|
||||
ax.set_title("区域划分与车-机-巢系统覆盖")
|
||||
ax.set_xlabel("区域宽度")
|
||||
ax.set_ylabel("区域高度")
|
||||
|
||||
# 定义若干颜色以区分不同系统(系统编号从0开始)
|
||||
colors = ['red', 'blue', 'green', 'orange', 'purple', 'cyan', 'magenta']
|
||||
|
||||
# 绘制区域中心
|
||||
region_center = (W / 2.0, H / 2.0) # 注意:x对应宽度,y对应高度
|
||||
ax.plot(region_center[0], region_center[1],
|
||||
'ko', markersize=8, label="区域中心")
|
||||
|
||||
# 绘制每个任务区域(矩形)及在矩形中心标注系统编号与卸载比率 ρ
|
||||
for system_id, tasks in best_solution['system_tasks'].items():
|
||||
# 重新按车辆行驶顺序排序(启发式:以任务中心距离区域中心的距离排序)
|
||||
tasks_sorted = sorted(tasks, key=lambda task: math.hypot(
|
||||
(task['c1'] + (task['c2'] - task['c1']) / 2.0) - region_center[0],
|
||||
(task['r1'] + (task['r2'] - task['r1']) / 2.0) - region_center[1]
|
||||
))
|
||||
|
||||
for i, task in enumerate(tasks_sorted, 1):
|
||||
# 绘制矩形:左下角坐标为 (c1, r1),宽度为 (c2 - c1),高度为 (r2 - r1)
|
||||
rect = patches.Rectangle((task['c1'], task['r1']),
|
||||
task['c2'] - task['c1'],
|
||||
task['r2'] - task['r1'],
|
||||
linewidth=2,
|
||||
edgecolor=colors[system_id % len(colors)],
|
||||
facecolor='none')
|
||||
ax.add_patch(rect)
|
||||
# 计算矩形中心
|
||||
center_x = task['c1'] + (task['c2'] - task['c1']) / 2.0
|
||||
center_y = task['r1'] + (task['r2'] - task['r1']) / 2.0
|
||||
# 在矩形中心标注:系统编号、执行顺序和卸载比率 ρ
|
||||
ax.text(center_x, center_y, f"S{system_id}-{i}\nρ={task['rho']:.2f}",
|
||||
color=colors[system_id % len(colors)],
|
||||
ha='center', va='center', fontsize=10, fontweight='bold')
|
||||
|
||||
# 添加图例
|
||||
ax.legend()
|
||||
# 反转 y 轴使得行号从上到下递增(如需,可取消)
|
||||
ax.invert_yaxis()
|
||||
plt.show()
|
||||
else:
|
||||
print("没有找到满足约束条件的方案,无法进行可视化。")
|
||||
|
61
visualization.py
Normal file
61
visualization.py
Normal file
@ -0,0 +1,61 @@
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib.patches as patches
|
||||
import json
|
||||
|
||||
def visualize_solution(row_boundaries, col_boundaries, car_paths, W, H):
|
||||
plt.rcParams['font.family'] = ['sans-serif']
|
||||
plt.rcParams['font.sans-serif'] = ['SimHei']
|
||||
fig, ax = plt.subplots()
|
||||
ax.set_xlim(0, W)
|
||||
ax.set_ylim(0, H)
|
||||
ax.set_title("区域划分与车-机-巢系统覆盖")
|
||||
ax.set_xlabel("区域宽度")
|
||||
ax.set_ylabel("区域高度")
|
||||
|
||||
# 定义若干颜色以区分不同系统(系统编号从0开始)
|
||||
colors = ['red', 'blue', 'green', 'orange', 'purple', 'cyan', 'magenta']
|
||||
|
||||
# 绘制区域中心
|
||||
region_center = (H / 2.0, W / 2.0) # 注意:x对应宽度,y对应高度
|
||||
ax.plot(region_center[1], region_center[0],
|
||||
'ko', markersize=8, label="区域中心")
|
||||
|
||||
# 绘制行分割边界
|
||||
for row in row_boundaries:
|
||||
ax.axhline(y=row * H, color='black', linestyle='--')
|
||||
|
||||
# 绘制列分割边界
|
||||
for col in col_boundaries:
|
||||
ax.axvline(x=col * W, color='black', linestyle='--')
|
||||
|
||||
# 绘制每辆车的轨迹
|
||||
for system_id, path in car_paths.items():
|
||||
path = [(region_center[0], region_center[1])] + path + [(region_center[0], region_center[1])]
|
||||
y, x = zip(*path)
|
||||
ax.plot(x, y, marker='o', color=colors[int(system_id) % len(colors)], label=f"系统 {system_id}")
|
||||
|
||||
# 添加图例
|
||||
ax.legend()
|
||||
# 反转 y 轴使得行号从上到下递增(如需,可取消)
|
||||
ax.invert_yaxis()
|
||||
plt.show()
|
||||
|
||||
if __name__ == "__main__":
|
||||
import yaml
|
||||
|
||||
# 读取参数
|
||||
with open('params.yml', 'r', encoding='utf-8') as file:
|
||||
params = yaml.safe_load(file)
|
||||
|
||||
H = params['H']
|
||||
W = params['W']
|
||||
|
||||
# 读取最佳方案的JSON文件
|
||||
with open('./solutions/best_solution_mtkl.json', 'r', encoding='utf-8') as f:
|
||||
best_solution = json.load(f)
|
||||
|
||||
row_boundaries = best_solution['row_boundaries']
|
||||
col_boundaries = best_solution['col_boundaries']
|
||||
car_paths = best_solution['car_paths']
|
||||
|
||||
visualize_solution(row_boundaries, col_boundaries, car_paths, W, H)
|
Loading…
Reference in New Issue
Block a user