From fe37f7ac0f6bb329131ce821a9547675f149235b Mon Sep 17 00:00:00 2001 From: weixin_46229132 Date: Mon, 24 Mar 2025 17:09:51 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=B6=85=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- GA/main.py | 13 +++++- GA/main_parallel.py | 15 +++++-- GA/sa_finetune.py | 12 ++++-- mtkl_sovler.py | 22 ++++++---- solutions/mtkl_params2.json | 30 ++++++++++++++ solutions/trav_ga_params2_parallel.json | 30 ++++++++++++++ visualization.py | 55 +++++++++++++++++++++---- 7 files changed, 150 insertions(+), 27 deletions(-) create mode 100644 solutions/mtkl_params2.json create mode 100644 solutions/trav_ga_params2_parallel.json diff --git a/GA/main.py b/GA/main.py index 746758a..dee6286 100644 --- a/GA/main.py +++ b/GA/main.py @@ -14,7 +14,15 @@ best_solution = None best_row_boundaries = None best_col_boundaries = None + +# --------------------------- +# 需要修改的超参数 +# --------------------------- +R = 3 +C = 3 params_file = 'params3' + + with open(params_file + '.yml', 'r', encoding='utf-8') as file: params = yaml.safe_load(file) @@ -37,13 +45,13 @@ battery_energy_capacity = params['battery_energy_capacity'] numbers = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9] # 生成所有的排列情况(取三次,每次都可以从10个数中选) -row_product = list(product(numbers, repeat=1)) +row_product = list(product(numbers, repeat=R)) # 对每种情况从小到大排序,并剔除重复的情况 row_cuts_set = set( tuple(sorted(set(item for item in prod if item > 0))) for prod in row_product) row_cuts_set = sorted(row_cuts_set) -col_product = list(product(numbers, repeat=1)) +col_product = list(product(numbers, repeat=C)) col_cuts_set = set( tuple(sorted(set(item for item in prod if item > 0))) for prod in col_product) col_cuts_set = sorted(col_cuts_set) @@ -95,6 +103,7 @@ print("Best solution:", best_solution) print("Time:", best_T) print("Row boundaries:", best_row_boundaries) print("Col boundaries:", best_col_boundaries) +print("Car Paths:", car_paths) output_data = { 'row_boundaries': best_row_boundaries, diff --git a/GA/main_parallel.py b/GA/main_parallel.py index b14de8d..98135f0 100644 --- a/GA/main_parallel.py +++ b/GA/main_parallel.py @@ -27,7 +27,14 @@ if __name__ == "__main__": # 重要:在 Windows 上必须加这一行 np.random.seed(42) random.seed(42) - params_file = 'params3' + # --------------------------- + # 需要修改的超参数 + # --------------------------- + R = 3 + C = 1 + params_file = 'params2' + batch_size = 60 # 控制一次最多并行多少个任务 + with open(params_file + '.yml', 'r', encoding='utf-8') as file: params = yaml.safe_load(file) @@ -50,13 +57,13 @@ if __name__ == "__main__": # 重要:在 Windows 上必须加这一行 numbers = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9] # 生成所有的排列情况(取三次,每次都可以从10个数中选) - row_product = list(product(numbers, repeat=1)) + row_product = list(product(numbers, repeat=R)) # 对每种情况从小到大排序,并剔除重复的情况 row_cuts_set = set( tuple(sorted(set(item for item in prod if item > 0))) for prod in row_product) row_cuts_set = sorted(row_cuts_set) - col_product = list(product(numbers, repeat=1)) + col_product = list(product(numbers, repeat=C)) col_cuts_set = set( tuple(sorted(set(item for item in prod if item > 0))) for prod in col_product) col_cuts_set = sorted(col_cuts_set) @@ -65,7 +72,6 @@ if __name__ == "__main__": # 重要:在 Windows 上必须加这一行 best_solution = None best_row_boundaries = None best_col_boundaries = None - batch_size = 60 # 控制一次最多并行多少个任务 all_tasks = [(row_cuts, col_cuts) for row_cuts in row_cuts_set for col_cuts in col_cuts_set] @@ -123,6 +129,7 @@ if __name__ == "__main__": # 重要:在 Windows 上必须加这一行 print("Time:", best_T) print("Row boundaries:", best_row_boundaries) print("Col boundaries:", best_col_boundaries) + print("Car Paths:", car_paths) output_data = { 'row_boundaries': best_row_boundaries, diff --git a/GA/sa_finetune.py b/GA/sa_finetune.py index 82744a4..fc5bbcb 100644 --- a/GA/sa_finetune.py +++ b/GA/sa_finetune.py @@ -203,12 +203,18 @@ def load_initial_solution(file_path): if __name__ == "__main__": random.seed(42) - # 从 JSON 文件加载初始解 - file_path = r"e:\studio2\HPCC_code\solutions\trav_ga_params3_parallel.json" + # --------------------------- + # 需要修改的超参数 + # --------------------------- + file_path = r"solutions\trav_ga_params2_parallel.json" + max_iterations=10000 + initial_temp=100 + cooling_rate=0.95 + initial_row_cuts, initial_col_cuts, car_paths = load_initial_solution( file_path) - sa = SA_FineTuner(initial_row_cuts, initial_col_cuts, car_paths) + sa = SA_FineTuner(initial_row_cuts, initial_col_cuts, car_paths, max_iterations, initial_temp, cooling_rate) best_row_cuts, best_col_cuts, best_T = sa.run() # 输出结果 diff --git a/mtkl_sovler.py b/mtkl_sovler.py index b765d2c..2ac7f00 100644 --- a/mtkl_sovler.py +++ b/mtkl_sovler.py @@ -7,12 +7,20 @@ import numpy as np # 固定随机种子,便于复现 random.seed(42) -num_iterations = 10000 # --------------------------- -# 参数设置 +# 需要修改的超参数 # --------------------------- -params_file = 'params3' +num_iterations = 10000 +# 随机生成分区的行分段数与列分段数 +# R = random.randint(0, 3) # 行分段数 +# C = random.randint(0, 3) # 列分段数 +R = 3 +C = 1 + +params_file = 'params2' + + with open(params_file + '.yml', 'r', encoding='utf-8') as file: params = yaml.safe_load(file) @@ -38,12 +46,6 @@ best_T = float('inf') best_solution = None for iteration in range(num_iterations): - # 随机生成分区的行分段数与列分段数 - # R = random.randint(0, 3) # 行分段数 - # C = random.randint(0, 3) # 列分段数 - R = 1 - C = 1 - # 生成随机的行、列分割边界 horiz = [np.clip(np.floor(random.random() * 10) / 10, 0.0, 0.9) for _ in range(R)] @@ -174,6 +176,8 @@ for iteration in range(num_iterations): # --------------------------- if best_solution is not None: print("最佳 T:", best_solution['T_max']) + print("Row boundaries:", best_solution['row_boundaries']) + print("Col boundaries:", best_solution['col_boundaries']) print("最佳路径:", best_solution['car_paths']) # 保存分区边界和车辆轨迹到JSON文件 diff --git a/solutions/mtkl_params2.json b/solutions/mtkl_params2.json new file mode 100644 index 0000000..2f4292c --- /dev/null +++ b/solutions/mtkl_params2.json @@ -0,0 +1,30 @@ +{ + "row_boundaries": [ + 0.0, + 0.3, + 0.4, + 0.7, + 1.0 + ], + "col_boundaries": [ + 0.0, + 0.5, + 1.0 + ], + "car_paths": [ + [ + 2, + 0 + ], + [ + 4, + 5, + 3, + 1 + ], + [ + 6, + 7 + ] + ] +} \ No newline at end of file diff --git a/solutions/trav_ga_params2_parallel.json b/solutions/trav_ga_params2_parallel.json new file mode 100644 index 0000000..e5e72ed --- /dev/null +++ b/solutions/trav_ga_params2_parallel.json @@ -0,0 +1,30 @@ +{ + "row_boundaries": [ + 0.0, + 0.2, + 0.4, + 0.7, + 1.0 + ], + "col_boundaries": [ + 0.0, + 0.5, + 1.0 + ], + "car_paths": [ + [ + 7, + 6 + ], + [ + 4, + 2, + 0 + ], + [ + 1, + 3, + 5 + ] + ] +} \ No newline at end of file diff --git a/visualization.py b/visualization.py index f3768c4..583ebe1 100644 --- a/visualization.py +++ b/visualization.py @@ -2,7 +2,8 @@ import matplotlib.pyplot as plt import matplotlib.patches as patches import json -def visualize_solution(row_boundaries, col_boundaries, car_paths, W, H): + +def visualize_solution(row_boundaries, col_boundaries, car_paths_coords, W, H): plt.rcParams['font.family'] = ['sans-serif'] plt.rcParams['font.sans-serif'] = ['SimHei'] fig, ax = plt.subplots() @@ -28,32 +29,68 @@ def visualize_solution(row_boundaries, col_boundaries, car_paths, W, H): for col in col_boundaries: ax.axvline(x=col * W, color='black', linestyle='--') - # 绘制每辆车的轨迹 - for system_id, path in enumerate(car_paths): - path = [(region_center[0], region_center[1])] + path + [(region_center[0], region_center[1])] + # 绘制每辆车的轨迹并标注区域序号 + for system_id, path in enumerate(car_paths_coords): + 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.plot(x, y, marker='o', color=colors[int( + system_id) % len(colors)], label=f"系统 {system_id}") + + # 标注每个区域的序号 + for idx, (px, py) in enumerate(zip(x[1:-1], y[1:-1])): # 跳过起点和终点 + ax.text(px, py, str(idx), color='black', fontsize=8, ha='center', va='center') # 添加图例 ax.legend() plt.show() + if __name__ == "__main__": import yaml - # 读取参数 - with open('params3.yml', 'r', encoding='utf-8') as file: + # --------------------------- + # 需要修改的超参数 + # --------------------------- + params_file = 'params2' + solution_file = r'solutions\trav_ga_params2_parallel.json' + + with open(params_file + '.yml', 'r', encoding='utf-8') as file: params = yaml.safe_load(file) H = params['H'] W = params['W'] + k = params['num_cars'] # 读取最佳方案的JSON文件 - with open(r'solutions\trav_ga_params3_parallel.json', 'r', encoding='utf-8') as f: + with open(solution_file, '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) \ No newline at end of file + # 计算分块区域的中心点坐标 + rectangle_centers = [] + for i in range(len(row_boundaries) - 1): + for j in range(len(col_boundaries) - 1): + r1 = row_boundaries[i] + r2 = row_boundaries[i + 1] + c1 = col_boundaries[j] + c2 = col_boundaries[j + 1] + d = (r2 - r1) * H * (c2 - c1) * W # 任务的照片数量(矩形面积) + + # 计算任务矩形中心,用于后续车辆移动时间计算 + center_r = (r1 + r2) / 2.0 * H + center_c = (c1 + c2) / 2.0 * W + + rectangle_centers.append((center_r, center_c)) + + # 将car_paths里的index换成坐标 + car_paths_coords = [[] for _ in range(k)] + for car_idx in range(k): + car_path = car_paths[car_idx] + for point in car_path: + car_paths_coords[car_idx].append(rectangle_centers[point]) + + visualize_solution(row_boundaries, col_boundaries, car_paths_coords, W, H)