添加遍历-遗传算法求解
This commit is contained in:
parent
a9ee5ceec7
commit
c9db9244b3
2
GA/ga.py
2
GA/ga.py
@ -165,7 +165,7 @@ class GA(object):
|
|||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
flight_time += self.rectangles[point - 1]['flight_time'] # 注意,这里要减一!!!
|
flight_time += self.rectangles[point - 1]['flight_time'] # 注意,这里要减一!!!
|
||||||
bs_time += self.rectangles[point - 1]['comp_bs_time']
|
bs_time += self.rectangles[point - 1]['bs_time']
|
||||||
system_time = max(flight_time + car_info['car_time'], bs_time)
|
system_time = max(flight_time + car_info['car_time'], bs_time)
|
||||||
T_k_list.append(system_time)
|
T_k_list.append(system_time)
|
||||||
T_max = max(T_k_list)
|
T_max = max(T_k_list)
|
||||||
|
101
GA/main.py
Normal file
101
GA/main.py
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
import random
|
||||||
|
import math
|
||||||
|
import yaml
|
||||||
|
import numpy as np
|
||||||
|
from utils import if_valid_partition, GA_solver
|
||||||
|
from itertools import product
|
||||||
|
import json
|
||||||
|
from tqdm import tqdm
|
||||||
|
|
||||||
|
np.random.seed(42)
|
||||||
|
random.seed(42)
|
||||||
|
best_T = float('inf')
|
||||||
|
best_solution = None
|
||||||
|
best_row_boundaries = None
|
||||||
|
best_col_boundaries = None
|
||||||
|
|
||||||
|
params_file = 'params2.yml'
|
||||||
|
with open(params_file, 'r', encoding='utf-8') as file:
|
||||||
|
params = yaml.safe_load(file)
|
||||||
|
|
||||||
|
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']
|
||||||
|
car_time_factor = params['car_time_factor']
|
||||||
|
bs_time_factor = params['bs_time_factor']
|
||||||
|
|
||||||
|
flight_energy_factor = params['flight_energy_factor']
|
||||||
|
comp_energy_factor = params['comp_energy_factor']
|
||||||
|
trans_energy_factor = params['trans_energy_factor']
|
||||||
|
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=3))
|
||||||
|
# 对每种情况从小到大排序,并剔除重复的情况
|
||||||
|
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=3))
|
||||||
|
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)
|
||||||
|
|
||||||
|
total_iterations = len(row_cuts_set) * len(col_cuts_set)
|
||||||
|
with tqdm(total=total_iterations, desc="Processing") as pbar:
|
||||||
|
for row_cuts in row_cuts_set:
|
||||||
|
for col_cuts in col_cuts_set:
|
||||||
|
row_boundaries = [0.0] + list(row_cuts) + [1.0]
|
||||||
|
col_boundaries = [0.0] + list(col_cuts) + [1.0]
|
||||||
|
|
||||||
|
# 这里面的距离不再是比例,而是真实距离!
|
||||||
|
rectrangles = if_valid_partition(row_boundaries, col_boundaries, params)
|
||||||
|
if not rectrangles:
|
||||||
|
pbar.update(1)
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
# 使用遗传算法求出每一种网格划分的可行解,然后选择其中的最优解
|
||||||
|
current_solution, current_time, to_process_idx = GA_solver(rectrangles, k)
|
||||||
|
|
||||||
|
if current_time < best_T:
|
||||||
|
best_T = current_time
|
||||||
|
best_solution = current_solution
|
||||||
|
best_row_boundaries = row_boundaries
|
||||||
|
best_col_boundaries = col_boundaries
|
||||||
|
|
||||||
|
# 将best_solution分解成每个车队的路径
|
||||||
|
found_start_points_indices = []
|
||||||
|
for i in range(len(best_solution)):
|
||||||
|
if best_solution[i] in to_process_idx:
|
||||||
|
found_start_points_indices.append(i)
|
||||||
|
car_paths = []
|
||||||
|
for j in range(len(found_start_points_indices) - 1):
|
||||||
|
from_index = found_start_points_indices[j]
|
||||||
|
end_index = found_start_points_indices[j + 1]
|
||||||
|
car_path = []
|
||||||
|
for k in range(from_index, end_index + 1):
|
||||||
|
rectrangle_idx = best_solution[k]
|
||||||
|
car_path.append(rectrangles[rectrangle_idx]['center'])
|
||||||
|
car_paths.append(car_path)
|
||||||
|
pbar.update(1)
|
||||||
|
|
||||||
|
# 输出最佳方案
|
||||||
|
print("Best solution:", best_solution)
|
||||||
|
print("Time:", best_T)
|
||||||
|
print("Row boundaries:", best_row_boundaries)
|
||||||
|
print("Col boundaries:", best_col_boundaries)
|
||||||
|
|
||||||
|
output_data = {
|
||||||
|
'row_boundaries': row_boundaries,
|
||||||
|
'col_boundaries': col_boundaries,
|
||||||
|
'car_paths': car_paths
|
||||||
|
}
|
||||||
|
with open(f'./solutions/traverse_ga_{params_file}.json', 'w', encoding='utf-8') as file:
|
||||||
|
json.dump(output_data, file, ensure_ascii=False, indent=4)
|
130
GA/main_parallel.py
Normal file
130
GA/main_parallel.py
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
import random
|
||||||
|
import math
|
||||||
|
import yaml
|
||||||
|
import numpy as np
|
||||||
|
from utils import if_valid_partition, GA_solver
|
||||||
|
from itertools import product
|
||||||
|
import json
|
||||||
|
from tqdm import tqdm
|
||||||
|
from concurrent.futures import ProcessPoolExecutor, as_completed
|
||||||
|
|
||||||
|
np.random.seed(42)
|
||||||
|
random.seed(42)
|
||||||
|
|
||||||
|
|
||||||
|
params_file = 'params2.yml'
|
||||||
|
with open(params_file, 'r', encoding='utf-8') as file:
|
||||||
|
params = yaml.safe_load(file)
|
||||||
|
|
||||||
|
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']
|
||||||
|
car_time_factor = params['car_time_factor']
|
||||||
|
bs_time_factor = params['bs_time_factor']
|
||||||
|
|
||||||
|
flight_energy_factor = params['flight_energy_factor']
|
||||||
|
comp_energy_factor = params['comp_energy_factor']
|
||||||
|
trans_energy_factor = params['trans_energy_factor']
|
||||||
|
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=3))
|
||||||
|
# 对每种情况从小到大排序,并剔除重复的情况
|
||||||
|
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=3))
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
def process_partition(row_cuts, col_cuts):
|
||||||
|
row_boundaries = [0.0] + list(row_cuts) + [1.0]
|
||||||
|
col_boundaries = [0.0] + list(col_cuts) + [1.0]
|
||||||
|
rectrangles = if_valid_partition(row_boundaries, col_boundaries, params)
|
||||||
|
|
||||||
|
if not rectrangles:
|
||||||
|
return None # 过滤无效划分
|
||||||
|
|
||||||
|
current_solution, current_time, to_process_idx = GA_solver(rectrangles, k)
|
||||||
|
|
||||||
|
return (current_solution, current_time, row_boundaries, col_boundaries, to_process_idx, rectrangles)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__": # 重要:在 Windows 上必须加这一行
|
||||||
|
best_T = float('inf')
|
||||||
|
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]
|
||||||
|
total_iterations = len(all_tasks)
|
||||||
|
|
||||||
|
with ProcessPoolExecutor(max_workers=batch_size) as executor:
|
||||||
|
futures = set()
|
||||||
|
results = []
|
||||||
|
|
||||||
|
with tqdm(total=total_iterations) as pbar:
|
||||||
|
for task in all_tasks:
|
||||||
|
if len(futures) >= batch_size: # 如果并行任务数达到 batch_size,等待已有任务完成
|
||||||
|
for future in as_completed(futures):
|
||||||
|
results.append(future.result())
|
||||||
|
pbar.update(1) # 更新进度条
|
||||||
|
futures.clear() # 清空已完成的任务
|
||||||
|
|
||||||
|
futures.add(executor.submit(process_partition, *task)) # 提交新任务
|
||||||
|
|
||||||
|
# 处理剩余未完成的任务
|
||||||
|
for future in as_completed(futures):
|
||||||
|
results.append(future.result())
|
||||||
|
pbar.update(1)
|
||||||
|
|
||||||
|
# 处理计算结果,找到最优解
|
||||||
|
for result in results:
|
||||||
|
if result:
|
||||||
|
current_solution, current_time, row_boundaries, col_boundaries, to_process_idx, rectrangles = result
|
||||||
|
if current_time < best_T:
|
||||||
|
best_T = current_time
|
||||||
|
best_solution = current_solution
|
||||||
|
best_row_boundaries = row_boundaries
|
||||||
|
best_col_boundaries = col_boundaries
|
||||||
|
|
||||||
|
# 解析最佳路径
|
||||||
|
found_start_points_indices = []
|
||||||
|
for i in range(len(best_solution)):
|
||||||
|
if best_solution[i] in to_process_idx:
|
||||||
|
found_start_points_indices.append(i)
|
||||||
|
car_paths = []
|
||||||
|
for j in range(len(found_start_points_indices) - 1):
|
||||||
|
from_index = found_start_points_indices[j]
|
||||||
|
end_index = found_start_points_indices[j + 1]
|
||||||
|
car_path = []
|
||||||
|
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]['center'])
|
||||||
|
car_paths.append(car_path)
|
||||||
|
|
||||||
|
# 输出最佳方案
|
||||||
|
print("Best solution:", best_solution)
|
||||||
|
print("Time:", best_T)
|
||||||
|
print("Row boundaries:", best_row_boundaries)
|
||||||
|
print("Col boundaries:", best_col_boundaries)
|
||||||
|
|
||||||
|
output_data = {
|
||||||
|
'row_boundaries': row_boundaries,
|
||||||
|
'col_boundaries': col_boundaries,
|
||||||
|
'car_paths': car_paths
|
||||||
|
}
|
||||||
|
with open(f'./solutions/travse_ga_{params_file}.json', 'w', encoding='utf-8') as file:
|
||||||
|
json.dump(output_data, file, ensure_ascii=False, indent=4)
|
93
GA/utils.py
Normal file
93
GA/utils.py
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
import numpy as np
|
||||||
|
from ga import GA
|
||||||
|
|
||||||
|
|
||||||
|
def if_valid_partition(row_boundaries, col_boundaries, params):
|
||||||
|
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']
|
||||||
|
car_time_factor = params['car_time_factor']
|
||||||
|
bs_time_factor = params['bs_time_factor']
|
||||||
|
|
||||||
|
flight_energy_factor = params['flight_energy_factor']
|
||||||
|
comp_energy_factor = params['comp_energy_factor']
|
||||||
|
trans_energy_factor = params['trans_energy_factor']
|
||||||
|
battery_energy_capacity = params['battery_energy_capacity']
|
||||||
|
|
||||||
|
# 根据分割边界生成所有矩形任务
|
||||||
|
rectangles = []
|
||||||
|
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 # 任务的照片数量(矩形面积)
|
||||||
|
|
||||||
|
# 求解rho
|
||||||
|
rho_time_limit = (flight_time_factor - trans_time_factor) / \
|
||||||
|
(comp_time_factor - trans_time_factor)
|
||||||
|
rho_energy_limit = (battery_energy_capacity - flight_energy_factor * d - trans_energy_factor * d) / \
|
||||||
|
(comp_energy_factor * d - trans_energy_factor * d)
|
||||||
|
if rho_energy_limit < 0:
|
||||||
|
return []
|
||||||
|
|
||||||
|
rho = min(rho_time_limit, rho_energy_limit)
|
||||||
|
flight_time = flight_time_factor * d
|
||||||
|
comp_time = comp_time_factor * rho * d
|
||||||
|
trans_time = trans_time_factor * (1 - rho) * d
|
||||||
|
bs_time = bs_time_factor * (1 - rho) * d
|
||||||
|
|
||||||
|
# 计算任务矩形中心,用于后续车辆移动时间计算
|
||||||
|
center_r = (r1 + r2) / 2.0 * H
|
||||||
|
center_c = (c1 + c2) / 2.0 * W
|
||||||
|
|
||||||
|
rectangles.append({
|
||||||
|
# 'r1': r1, 'r2': r2, 'c1': c1, 'c2': c2,
|
||||||
|
'd': d,
|
||||||
|
'rho': rho,
|
||||||
|
'flight_time': flight_time,
|
||||||
|
'comp_time': comp_time,
|
||||||
|
'trans_time': trans_time,
|
||||||
|
'bs_time': bs_time,
|
||||||
|
'center': (center_r, center_c)
|
||||||
|
})
|
||||||
|
return rectangles
|
||||||
|
|
||||||
|
|
||||||
|
def GA_solver(rectangles, k):
|
||||||
|
num_city = len(rectangles) + 1 # 划分好的区域中心点+整个区域的中心
|
||||||
|
|
||||||
|
# 初始化坐标 (第一个点是整个区域的中心)
|
||||||
|
center_data = [[1 / 2.0, 1 / 2.0]]
|
||||||
|
for rec in rectangles:
|
||||||
|
center_data.append(rec['center'])
|
||||||
|
center_data = np.array(center_data)
|
||||||
|
|
||||||
|
# 关键:有k架无人机,则再增加N-1个`点` (坐标是起始点),这些点之间的距离是inf
|
||||||
|
for d in range(k - 1):
|
||||||
|
center_data = np.vstack([center_data, center_data[0]])
|
||||||
|
num_city += 1 # 增加欺骗城市
|
||||||
|
|
||||||
|
to_process_idx = [0]
|
||||||
|
# print("start point:", location[0])
|
||||||
|
for d in range(1, k): # 1, ... drone-1
|
||||||
|
# print("added base point:", location[num_city - d])
|
||||||
|
to_process_idx.append(num_city - d)
|
||||||
|
|
||||||
|
model = GA(num_drones=k, num_city=center_data.shape[0], num_total=20, data=center_data.copy(
|
||||||
|
), to_process_idx=to_process_idx, rectangles=rectangles)
|
||||||
|
Best_path, Best = model.run()
|
||||||
|
|
||||||
|
# 根据最佳路径计算各系统任务分配
|
||||||
|
if Best_path[0] not in to_process_idx:
|
||||||
|
Best_path.insert(0, 0)
|
||||||
|
|
||||||
|
if Best_path[-1] not in to_process_idx:
|
||||||
|
Best_path.append(0)
|
||||||
|
|
||||||
|
return Best_path, Best, to_process_idx
|
9
env.py
9
env.py
@ -244,25 +244,25 @@ class PartitionMazeEnv(gym.Env):
|
|||||||
new_row = current_row - 1
|
new_row = current_row - 1
|
||||||
else: # 错误的移动给一些惩罚?
|
else: # 错误的移动给一些惩罚?
|
||||||
new_row = current_row
|
new_row = current_row
|
||||||
# reward -= 10
|
# reward -= 1
|
||||||
elif move_dir == 'down':
|
elif move_dir == 'down':
|
||||||
if current_row < len(self.row_cuts) - 2:
|
if current_row < len(self.row_cuts) - 2:
|
||||||
new_row = current_row + 1
|
new_row = current_row + 1
|
||||||
else:
|
else:
|
||||||
new_row = current_row
|
new_row = current_row
|
||||||
# reward -= 10
|
# reward -= 1
|
||||||
elif move_dir == 'left':
|
elif move_dir == 'left':
|
||||||
if current_col > 0:
|
if current_col > 0:
|
||||||
new_col = current_col - 1
|
new_col = current_col - 1
|
||||||
else:
|
else:
|
||||||
new_col = current_col
|
new_col = current_col
|
||||||
# reward -= 10
|
# reward -= 1
|
||||||
elif move_dir == 'right':
|
elif move_dir == 'right':
|
||||||
if current_col < len(self.col_cuts) - 2:
|
if current_col < len(self.col_cuts) - 2:
|
||||||
new_col = current_col + 1
|
new_col = current_col + 1
|
||||||
else:
|
else:
|
||||||
new_col = current_col
|
new_col = current_col
|
||||||
# reward -= 10
|
# reward -= 1
|
||||||
# 如果移动不合法,或者动作为stay,则保持原位置
|
# 如果移动不合法,或者动作为stay,则保持原位置
|
||||||
|
|
||||||
# 检查是否移动
|
# 检查是否移动
|
||||||
@ -320,7 +320,6 @@ class PartitionMazeEnv(gym.Env):
|
|||||||
# # TODO 让奖励在baseline附近变化更剧烈
|
# # TODO 让奖励在baseline附近变化更剧烈
|
||||||
# # reward = math.exp(-T / self.BASE_LINE) * 1000
|
# # reward = math.exp(-T / self.BASE_LINE) * 1000
|
||||||
reward += self.BASE_LINE / real_T * 5
|
reward += self.BASE_LINE / real_T * 5
|
||||||
print(real_T, "="*20)
|
|
||||||
|
|
||||||
# if reward > self.BASE_LINE:
|
# if reward > self.BASE_LINE:
|
||||||
# reward -= 200
|
# reward -= 200
|
||||||
|
@ -12,7 +12,8 @@ num_iterations = 10000
|
|||||||
# ---------------------------
|
# ---------------------------
|
||||||
# 参数设置
|
# 参数设置
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
with open('params.yml', 'r', encoding='utf-8') as file:
|
params_file = 'params2.yml'
|
||||||
|
with open(params_file, 'r', encoding='utf-8') as file:
|
||||||
params = yaml.safe_load(file)
|
params = yaml.safe_load(file)
|
||||||
|
|
||||||
H = params['H']
|
H = params['H']
|
||||||
@ -38,8 +39,8 @@ best_solution = None
|
|||||||
|
|
||||||
for iteration in range(num_iterations):
|
for iteration in range(num_iterations):
|
||||||
# 随机生成分区的行分段数与列分段数
|
# 随机生成分区的行分段数与列分段数
|
||||||
R = random.randint(0, 5) # 行分段数
|
R = random.randint(0, 3) # 行分段数
|
||||||
C = random.randint(0, 5) # 列分段数
|
C = random.randint(0, 3) # 列分段数
|
||||||
|
|
||||||
# 生成随机的行、列分割边界
|
# 生成随机的行、列分割边界
|
||||||
horiz = [np.clip(np.floor(random.random() * 10) /10, 0.0, 0.9) for _ in range(R)]
|
horiz = [np.clip(np.floor(random.random() * 10) /10, 0.0, 0.9) for _ in range(R)]
|
||||||
@ -174,7 +175,7 @@ if best_solution is not None:
|
|||||||
print("行分割边界:", best_solution['row_boundaries'])
|
print("行分割边界:", best_solution['row_boundaries'])
|
||||||
print("列分割边界:", best_solution['col_boundaries'])
|
print("列分割边界:", best_solution['col_boundaries'])
|
||||||
print("每辆车的运行轨迹情况:")
|
print("每辆车的运行轨迹情况:")
|
||||||
car_paths = {}
|
car_paths = []
|
||||||
for i in range(k):
|
for i in range(k):
|
||||||
num_tasks = len(best_solution['system_tasks'][i])
|
num_tasks = len(best_solution['system_tasks'][i])
|
||||||
print(
|
print(
|
||||||
@ -193,7 +194,7 @@ if best_solution is not None:
|
|||||||
print(
|
print(
|
||||||
f" -> 任务{j}({current_pos[0]:.1f}, {current_pos[1]:.1f})", end="")
|
f" -> 任务{j}({current_pos[0]:.1f}, {current_pos[1]:.1f})", end="")
|
||||||
print(" -> 区域中心")
|
print(" -> 区域中心")
|
||||||
car_paths[i] = car_path
|
car_paths.append(car_path)
|
||||||
|
|
||||||
# 保存分区边界和车辆轨迹到JSON文件
|
# 保存分区边界和车辆轨迹到JSON文件
|
||||||
output_data = {
|
output_data = {
|
||||||
@ -201,7 +202,7 @@ if best_solution is not None:
|
|||||||
'col_boundaries': [boundary / W for boundary in best_solution['col_boundaries']],
|
'col_boundaries': [boundary / W for boundary in best_solution['col_boundaries']],
|
||||||
'car_paths': car_paths
|
'car_paths': car_paths
|
||||||
}
|
}
|
||||||
with open('./solutions/best_solution_mtkl.json', 'w', encoding='utf-8') as f:
|
with open(f'./solutions/mtkl_{params_file}.json', 'w', encoding='utf-8') as f:
|
||||||
json.dump(output_data, f, ensure_ascii=False, indent=4)
|
json.dump(output_data, f, ensure_ascii=False, indent=4)
|
||||||
else:
|
else:
|
||||||
print("在给定的模拟次数内未找到满足所有约束的方案。")
|
print("在给定的模拟次数内未找到满足所有约束的方案。")
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
"row_boundaries": [
|
"row_boundaries": [
|
||||||
0.0,
|
0.0,
|
||||||
0.2,
|
0.3,
|
||||||
0.4,
|
0.6,
|
||||||
0.7,
|
0.8,
|
||||||
1.0
|
1.0
|
||||||
],
|
],
|
||||||
"col_boundaries": [
|
"col_boundaries": [
|
||||||
@ -11,44 +11,44 @@
|
|||||||
0.5,
|
0.5,
|
||||||
1.0
|
1.0
|
||||||
],
|
],
|
||||||
"car_paths": {
|
"car_paths": [
|
||||||
"0": [
|
|
||||||
[
|
[
|
||||||
15.0,
|
[
|
||||||
12.5
|
22.5,
|
||||||
|
37.5
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
5.0,
|
7.5,
|
||||||
12.5
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"1": [
|
|
||||||
[
|
|
||||||
42.5,
|
|
||||||
12.5
|
|
||||||
],
|
|
||||||
[
|
|
||||||
42.5,
|
|
||||||
37.5
|
37.5
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
"2": [
|
|
||||||
[
|
[
|
||||||
27.5,
|
[
|
||||||
|
7.5,
|
||||||
12.5
|
12.5
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
27.5,
|
45.0,
|
||||||
|
37.5
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[
|
||||||
|
22.5,
|
||||||
|
12.5
|
||||||
|
],
|
||||||
|
[
|
||||||
|
35.0,
|
||||||
|
12.5
|
||||||
|
],
|
||||||
|
[
|
||||||
|
35.0,
|
||||||
37.5
|
37.5
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
15.0,
|
45.0,
|
||||||
37.5
|
12.5
|
||||||
],
|
]
|
||||||
[
|
|
||||||
5.0,
|
|
||||||
37.5
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
|
@ -29,7 +29,7 @@ def visualize_solution(row_boundaries, col_boundaries, car_paths, W, H):
|
|||||||
ax.axvline(x=col * W, color='black', linestyle='--')
|
ax.axvline(x=col * W, color='black', linestyle='--')
|
||||||
|
|
||||||
# 绘制每辆车的轨迹
|
# 绘制每辆车的轨迹
|
||||||
for system_id, path in car_paths.items():
|
for system_id, path in enumerate(car_paths):
|
||||||
path = [(region_center[0], region_center[1])] + path + [(region_center[0], region_center[1])]
|
path = [(region_center[0], region_center[1])] + path + [(region_center[0], region_center[1])]
|
||||||
y, x = zip(*path)
|
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}")
|
||||||
|
Loading…
Reference in New Issue
Block a user