From 9599215e2ea081a5d5bf225bc1f2603128a91f9d Mon Sep 17 00:00:00 2001 From: weixin_46229132 Date: Mon, 24 Mar 2025 15:42:42 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A8=A1=E6=8B=9F=E9=80=80=E7=81=AB=E5=BE=AE?= =?UTF-8?q?=E8=B0=83=E5=88=86=E5=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- GA/ga.py | 2 +- GA/main.py | 3 +- GA/main_parallel.py | 6 +- GA/sa_finetune.py | 217 ++++++++++++++++++++++++ mtkl_sovler.py | 10 +- solutions/mtkl_params3.json | 20 +++ solutions/trav_ga_params3.json | 34 ++++ solutions/trav_ga_params3_parallel.json | 22 +++ 8 files changed, 304 insertions(+), 10 deletions(-) create mode 100644 GA/sa_finetune.py create mode 100644 solutions/mtkl_params3.json create mode 100644 solutions/trav_ga_params3.json create mode 100644 solutions/trav_ga_params3_parallel.json diff --git a/GA/ga.py b/GA/ga.py index 976c5ee..336d414 100644 --- a/GA/ga.py +++ b/GA/ga.py @@ -150,7 +150,7 @@ class GA(object): merged_path = first['car_path'] + second['car_path'] merged_time = first['car_time'] + second['car_time'] merged_dict = {'car_path': merged_path, 'car_time': merged_time} - sorted_car_infos = [merged_dict] + sorted_car_infos[3:] + sorted_car_infos = [merged_dict] + sorted_car_infos[2:] # 计算各系统的总时间max(飞行时间+车的时间, 机巢计算时间) T_k_list = [] diff --git a/GA/main.py b/GA/main.py index 7e2a1f3..746758a 100644 --- a/GA/main.py +++ b/GA/main.py @@ -85,8 +85,7 @@ with tqdm(total=total_iterations, desc="Processing") as pbar: for k in range(from_index, end_index + 1): rectrangle_idx = best_solution[k] if rectrangle_idx not in to_process_idx: - car_path.append( - rectrangles[rectrangle_idx - 1]['center']) + car_path.append(rectrangle_idx - 1) if car_path: car_paths.append(car_path) pbar.update(1) diff --git a/GA/main_parallel.py b/GA/main_parallel.py index 453544d..b14de8d 100644 --- a/GA/main_parallel.py +++ b/GA/main_parallel.py @@ -83,7 +83,8 @@ if __name__ == "__main__": # 重要:在 Windows 上必须加这一行 pbar.update(1) # 更新进度条 futures.clear() # 清空已完成的任务 - futures.add(executor.submit(process_partition, *task, params)) # 提交新任务 + futures.add(executor.submit( + process_partition, *task, params)) # 提交新任务 # 处理剩余未完成的任务 for future in as_completed(futures): @@ -113,8 +114,7 @@ if __name__ == "__main__": # 重要:在 Windows 上必须加这一行 for k in range(from_index, end_index + 1): rectrangle_idx = best_solution[k] if rectrangle_idx not in to_process_idx: - car_path.append( - rectrangles[rectrangle_idx - 1]['center']) + car_path.append(rectrangle_idx - 1) if car_path: car_paths.append(car_path) diff --git a/GA/sa_finetune.py b/GA/sa_finetune.py new file mode 100644 index 0000000..82744a4 --- /dev/null +++ b/GA/sa_finetune.py @@ -0,0 +1,217 @@ +import random +import math +import json +import yaml + + +class SA_FineTuner: + def __init__(self, initial_row_cuts, initial_col_cuts, car_paths, max_iterations=1000, initial_temp=100, cooling_rate=0.95): + """ + 初始化模拟退火算法 + :param initial_row_cuts: 初始行切分比例列表,例如 [0.1, 0.3, 0.7] + :param initial_col_cuts: 初始列切分比例列表,例如 [0.2, 0.5, 0.8] + :param T_function: 目标函数,用于计算切分比例的目标值 T + :param max_iterations: 最大迭代次数 + :param initial_temp: 初始温度 + :param cooling_rate: 温度下降速率 + """ + # 读取参数 + with open('params3.yml', 'r', encoding='utf-8') as file: + params = yaml.safe_load(file) + + self.H = params['H'] + self.W = params['W'] + self.num_cars = params['num_cars'] + + self.flight_time_factor = params['flight_time_factor'] + self.comp_time_factor = params['comp_time_factor'] + self.trans_time_factor = params['trans_time_factor'] + self.car_time_factor = params['car_time_factor'] + self.bs_time_factor = params['bs_time_factor'] + + self.flight_energy_factor = params['flight_energy_factor'] + self.comp_energy_factor = params['comp_energy_factor'] + self.trans_energy_factor = params['trans_energy_factor'] + self.battery_energy_capacity = params['battery_energy_capacity'] + + self.current_row_cuts = initial_row_cuts[:] + self.current_col_cuts = initial_col_cuts[:] + self.car_paths = car_paths + self.current_T = self.T_function( + self.current_row_cuts, self.current_col_cuts) # 初始目标值 + + self.best_row_cuts = self.current_row_cuts[:] + self.best_col_cuts = self.current_col_cuts[:] + self.best_T = self.current_T + + # 模拟退火相关参数 + self.max_iterations = max_iterations + self.initial_temp = initial_temp + self.cooling_rate = cooling_rate + self.temperature = initial_temp + + def fine_tune(self, cuts): + """ + 微调切分比例 + :param cuts: 当前切分比例列表,例如 [0.1, 0.3, 0.7] + :return: 微调后的切分比例列表 + """ + new_cuts = cuts[:] + if not new_cuts: + return new_cuts + + # 随机选择一个切分点进行微调 + index = random.randint(1, len(new_cuts) - 2) # 左闭右闭!!! + adjustment = random.choice([-0.01, 0.01]) # 固定步长调整 + new_cuts[index] += adjustment + + # 确保切分比例合法 + if new_cuts[index] >= new_cuts[index + 1]: + new_cuts[index] = new_cuts[index + 1] - 0.01 + elif new_cuts[index] <= new_cuts[index - 1]: + new_cuts[index] = new_cuts[index - 1] + 0.01 + else: + pass + new_cuts[index] = max(0.01, min(0.99, new_cuts[index])) + + return new_cuts + + def accept_solution(self, current_T, new_T, temperature): + """ + 判断是否接受新解 + :param current_T: 当前解的目标值 + :param new_T: 新解的目标值 + :param temperature: 当前温度 + :return: 是否接受新解(True/False) + """ + if new_T < current_T: + return True + else: + # 根据模拟退火的概率公式接受较差解 + delta = new_T - current_T + acceptance_probability = math.exp(-delta / temperature) + return random.random() < acceptance_probability + + def T_function(self, row_cuts, col_cuts): + """ + 计算切分比例的目标值 T(占位函数) + :param row_cuts: 行切分比例 + :param col_cuts: 列切分比例 + :return: 目标值 T + """ + rectangles = [] + for i in range(len(row_cuts) - 1): + for j in range(len(col_cuts) - 1): + d = (col_cuts[j+1] - col_cuts[j]) * self.W * \ + (row_cuts[i+1] - row_cuts[i]) * self.H + rho_time_limit = (self.flight_time_factor - self.trans_time_factor) / \ + (self.comp_time_factor - self.trans_time_factor) + rho_energy_limit = (self.battery_energy_capacity - self.flight_energy_factor * d - self.trans_energy_factor * d) / \ + (self.comp_energy_factor * d - + self.trans_energy_factor * d) + if rho_energy_limit < 0: + return float('inf') + rho = min(rho_time_limit, rho_energy_limit) + + flight_time = self.flight_time_factor * d + bs_time = self.bs_time_factor * (1 - rho) * d + + rectangles.append({ + 'flight_time': flight_time, + 'bs_time': bs_time, + 'center': ((row_cuts[i] + row_cuts[i+1]) / 2.0 * self.H, + (col_cuts[j] + col_cuts[j+1]) / 2.0 * self.W) + }) + + mortorcade_time_lt = [] + for idx in range(self.num_cars): + car_path = self.car_paths[idx] + + flight_time = sum(rectangles[point]['flight_time'] + for point in car_path) + bs_time = sum(rectangles[point]['bs_time'] for point in car_path) + + car_time = 0 + for i in range(len(car_path) - 1): + first_point = car_path[i] + second_point = car_path[i + 1] + car_time += math.dist( + rectangles[first_point]['center'], rectangles[second_point]['center']) * self.car_time_factor + car_time += math.dist(rectangles[0]['center'], + [self.H / 2, self.W / 2]) * self.car_time_factor + car_time += math.dist(rectangles[-1]['center'], + [self.H / 2, self.W / 2]) * self.car_time_factor + mortorcade_time_lt.append(max(car_time + flight_time, bs_time)) + + return max(mortorcade_time_lt) + + def run(self): + """ + 运行模拟退火算法 + :return: 最优行切分比例、最优列切分比例、最小目标值 T + """ + for iteration in range(self.max_iterations): + # 随机选择行或列进行微调 + if random.random() < 0.5: + new_row_cuts = self.fine_tune(self.current_row_cuts) + new_col_cuts = self.current_col_cuts[:] + else: + new_row_cuts = self.current_row_cuts[:] + new_col_cuts = self.fine_tune(self.current_col_cuts) + + # 计算新解的目标值 + new_T = self.T_function(new_row_cuts, new_col_cuts) + + # 判断是否接受新解 + if self.accept_solution(self.current_T, new_T, self.temperature): + self.current_row_cuts = new_row_cuts + self.current_col_cuts = new_col_cuts + self.current_T = new_T + + # 更新最优解 + if new_T < self.best_T: + self.best_row_cuts = new_row_cuts + self.best_col_cuts = new_col_cuts + self.best_T = new_T + + # 降低温度 + self.temperature *= self.cooling_rate + + # 打印进度(可选) + if iteration % 100 == 0: + print( + f"Iteration {iteration}: Best T = {self.best_T}, Temperature = {self.temperature}") + + return self.best_row_cuts, self.best_col_cuts, self.best_T + + +def load_initial_solution(file_path): + """ + 从 JSON 文件加载初始解 + :param file_path: JSON 文件路径 + :return: 行切分比例、列切分比例 + """ + with open(file_path, 'r', encoding='utf-8') as file: + data = json.load(file) + row_cuts = data['row_boundaries'] + col_cuts = data['col_boundaries'] + car_paths = data['car_paths'] + return row_cuts, col_cuts, car_paths + + +# 示例调用 +if __name__ == "__main__": + random.seed(42) + + # 从 JSON 文件加载初始解 + file_path = r"e:\studio2\HPCC_code\solutions\trav_ga_params3_parallel.json" + initial_row_cuts, initial_col_cuts, car_paths = load_initial_solution( + file_path) + + sa = SA_FineTuner(initial_row_cuts, initial_col_cuts, car_paths) + best_row_cuts, best_col_cuts, best_T = sa.run() + + # 输出结果 + print("Best row cuts:", best_row_cuts) + print("Best col cuts:", best_col_cuts) + print("Best T:", best_T) diff --git a/mtkl_sovler.py b/mtkl_sovler.py index 263826d..7eefd2e 100644 --- a/mtkl_sovler.py +++ b/mtkl_sovler.py @@ -12,8 +12,8 @@ num_iterations = 10000 # --------------------------- # 参数设置 # --------------------------- -params_file = 'params2.yml' -with open(params_file, 'r', encoding='utf-8') as file: +params_file = 'params3' +with open(params_file + '.yml', 'r', encoding='utf-8') as file: params = yaml.safe_load(file) H = params['H'] @@ -39,8 +39,10 @@ best_solution = None for iteration in range(num_iterations): # 随机生成分区的行分段数与列分段数 - R = random.randint(0, 3) # 行分段数 - C = random.randint(0, 3) # 列分段数 + # 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)] diff --git a/solutions/mtkl_params3.json b/solutions/mtkl_params3.json new file mode 100644 index 0000000..0b6846e --- /dev/null +++ b/solutions/mtkl_params3.json @@ -0,0 +1,20 @@ +{ + "row_boundaries": [ + 0.0, + 0.5, + 1.0 + ], + "col_boundaries": [ + 0.0, + 0.5, + 1.0 + ], + "car_paths": [ + [ + 0, 2 + ], + [ + 1, 3 + ] + ] +} \ No newline at end of file diff --git a/solutions/trav_ga_params3.json b/solutions/trav_ga_params3.json new file mode 100644 index 0000000..cb6e440 --- /dev/null +++ b/solutions/trav_ga_params3.json @@ -0,0 +1,34 @@ +{ + "row_boundaries": [ + 0.0, + 0.3, + 1.0 + ], + "col_boundaries": [ + 0.0, + 0.4, + 1.0 + ], + "car_paths": [ + [ + [ + 19.5, + 21.0 + ] + ], + [ + [ + 4.5, + 6.0 + ], + [ + 4.5, + 21.0 + ], + [ + 19.5, + 6.0 + ] + ] + ] +} \ No newline at end of file diff --git a/solutions/trav_ga_params3_parallel.json b/solutions/trav_ga_params3_parallel.json new file mode 100644 index 0000000..da3f6a7 --- /dev/null +++ b/solutions/trav_ga_params3_parallel.json @@ -0,0 +1,22 @@ +{ + "row_boundaries": [ + 0.0, + 0.5, + 1.0 + ], + "col_boundaries": [ + 0.0, + 0.5, + 1.0 + ], + "car_paths": [ + [ + 0, + 2 + ], + [ + 1, + 3 + ] + ] +} \ No newline at end of file