整线批量测试模式添加

This commit is contained in:
2025-11-27 17:57:42 +08:00
parent 369e439a97
commit 28adfab398
35 changed files with 13984 additions and 52 deletions

View File

@@ -24,6 +24,7 @@ def base_optimizer(machine_index, pcb_data, component_data, feeder_data, params,
placement_result, head_sequence = scan_based_placement_route_generation(component_data, pcb_data,
component_result, cycle_result,
feeder_slot_result)
elif params.machine_optimizer == 'hybrid-genetic': # 基于拾取组的混合遗传算法
component_result, cycle_result, feeder_slot_result, placement_result, head_sequence = optimizer_hybrid_genetic(
pcb_data, component_data, hinter=hinter)
@@ -61,7 +62,7 @@ def base_optimizer(machine_index, pcb_data, component_data, feeder_data, params,
# placement_route_schematic(pcb_data, component_data, opt_res, 1)
if params.save:
output_optimize_result(
f'result/{params.filename[:-4]}-{params.line_optimizer}-M0{machine_index} {params.save_suffix}',
f'result/{params.filename[:-4]}-{params.line_optimizer}-M0{machine_index}',
component_data, pcb_data, opt_res)
# output_optimize_result(f'{params.filename[:-4]}', component_data, pcb_data, opt_res)

View File

@@ -356,7 +356,7 @@ def output_optimize_result(file_path, component_data, pcb_data, optimizer_result
column_index = int(np.where(output_data.columns.values.reshape(-1) == 'part')[0][0])
output_data.insert(loc=column_index + 1, column='desc', value='')
output_data.to_csv('result/' + file_path + '.txt', sep='\t', float_format='%.3f', header=False, index=False)
output_data.to_csv(file_path + '.txt', sep='\t', float_format='%.3f', header=False, index=False)
def optimization_assign_result(component_data, pcb_data, optimizer_result, nozzle_hinter=False, component_hinter=False,
@@ -580,9 +580,9 @@ def placement_info_evaluation(component_data, pcb_data, optimizer_result, hinter
index = optimizer_result.placement_assign[cycle][head]
if index == -1:
continue
mount_pos.append([pcb_data.iloc[index]['x'] - head * head_interval + stopper_pos[0],
pcb_data.iloc[index]['y'] + stopper_pos[1]])
head_angle[head] = pcb_data.iloc[index]['r']
mount_pos.append([pcb_data.loc[index]['x'] - head * head_interval + stopper_pos[0],
pcb_data.loc[index]['y'] + stopper_pos[1]])
head_angle[head] = pcb_data.loc[index]['r']
# 单独计算贴装路径
for cntPoints in range(len(mount_pos) - 1):

View File

@@ -22,8 +22,8 @@ def dynamic_programming_cycle_path(pcb_data, cycle_placement, assigned_feeder):
head_set.append(head)
placement = cycle_placement[head]
pos.append([pcb_data.iloc[placement]['x'] - head * head_interval + stopper_pos[0],
pcb_data.iloc[placement]['y'] + stopper_pos[1], pcb_data.iloc[placement]['r'], head])
pos.append([pcb_data.loc[placement]['x'] - head * head_interval + stopper_pos[0],
pcb_data.loc[placement]['y'] + stopper_pos[1], pcb_data.loc[placement]['r'], head])
feeder_set.add(feeder - head * interval_ratio)
@@ -81,8 +81,8 @@ def dynamic_programming_cycle_path(pcb_data, cycle_placement, assigned_feeder):
head_sequence.append(head_set[parent - 1])
start_head, end_head = head_sequence[0], head_sequence[-1]
if pcb_data.iloc[cycle_placement[start_head]]['x'] - start_head * head_interval > \
pcb_data.iloc[cycle_placement[end_head]]['x'] - end_head * head_interval:
if pcb_data.loc[cycle_placement[start_head]]['x'] - start_head * head_interval > \
pcb_data.loc[cycle_placement[end_head]]['x'] - end_head * head_interval:
head_sequence = list(reversed(head_sequence))
return ans_dist, head_sequence
@@ -188,12 +188,12 @@ def place_allocate_sequence_route_generation(component_data, pcb_data, component
mount_point_index = [[] for _ in range(len(component_data))]
mount_point_pos = [[] for _ in range(len(component_data))]
for i in range(len(pcb_data)):
part = pcb_data.iloc[i]['part']
for idx, data in pcb_data.iterrows():
part = data.part
component_index = component_data[component_data['part'] == part].index.tolist()[0]
# 记录贴装点序号索引和对应的位置坐标
mount_point_index[component_index].append(i)
mount_point_pos[component_index].append([pcb_data.iloc[i]['x'], pcb_data.iloc[i]['y']])
mount_point_index[component_index].append(idx)
mount_point_pos[component_index].append([data.x, data.y])
search_dir = 0 # 0自左向右搜索 1自右向左搜索
for cycle_set in range(len(component_result)):
@@ -205,7 +205,7 @@ def place_allocate_sequence_route_generation(component_data, pcb_data, component
range(len(mount_point_pos)) if len(mount_point_pos[component_index]) > 0][0][0]
min_pos = [min(mount_point_pos[component_index], key=lambda x: x[0]) for component_index in
range(len(mount_point_pos)) if len(mount_point_pos[component_index]) > 0][0][0]
point2head_range = min(math.floor((max_pos - min_pos) / head_interval) + 1, max_head_index)
# point2head_range = min(math.floor((max_pos - min_pos) / head_interval) + 1, max_head_index)
# 最近邻确定
way_point = None
@@ -466,15 +466,16 @@ def scan_based_placement_route_generation(component_data, pcb_data, component_as
hinter=True):
placement_result, head_sequence_result = [], []
mount_point_pos, mount_point_index, mount_point_angle, mount_point_part = [], [], [], []
for _, data in pcb_data.iterrows():
mount_point_pos, mount_point_index, mount_point_angle = [], [], []
mount_point_part = defaultdict(int)
for idx, data in pcb_data.iterrows():
component_index = component_data[component_data.part == data.part].index.tolist()[0]
# 记录贴装点序号索引和对应的位置坐标
mount_point_index.append(len(mount_point_index))
mount_point_index.append(idx)
mount_point_pos.append([data.x + stopper_pos[0], data.y + stopper_pos[1]])
mount_point_angle.append(data.r)
mount_point_part.append(component_index)
mount_point_part[idx] = component_index
left_boundary, right_boundary = min(mount_point_pos, key=lambda x: x[0])[0], max(mount_point_pos, key=lambda x: x[0])[0]
search_step = max((right_boundary - left_boundary) / max_head_index / 2, 0)
@@ -603,22 +604,23 @@ def placement_route_relink_heuristic(component_data, pcb_data, placement_result,
cycle_group_index[cycle_index] = cycle_group
cycle_index += 1
mount_point_pos, mount_point_angle, mount_point_index, mount_point_part = [], [], [], []
mount_point_angle, mount_point_index = [], []
mount_point_pos, mount_point_part = defaultdict(list), defaultdict(int)
for i, data in pcb_data.iterrows():
component_index = component_data[component_data.part == data.part].index.tolist()[0]
# 记录贴装点序号索引和对应的位置坐标
mount_point_index.append(i)
mount_point_pos.append([data.x + stopper_pos[0], data.y + stopper_pos[1]])
mount_point_pos[i] = [data.x + stopper_pos[0], data.y + stopper_pos[1]]
mount_point_angle.append(data.r)
mount_point_part.append(component_index)
mount_point_part[i] = component_index
cycle_length, cycle_average_pos = [], []
for cycle, placement in enumerate(placement_result):
# prev_pos, prev_angle = None, None
cycle_pos_list = []
for idx, head in enumerate(head_sequence_result[cycle]):
if point_index := placement[head] == -1:
if (point_index := placement[head]) == -1:
continue
cycle_pos_list.append(
[mount_point_pos[point_index][0] - head * head_interval, mount_point_pos[point_index][1]])
@@ -825,9 +827,11 @@ class RouteNode:
def dynamic_beam_route_generation(component_data, pcb_data, component_assign, cycle_assign, feeder_assign):
empty_node = RouteNode(component_data, pcb_data)
max_beam_width = 4
point_pos = [Point(data.x + stopper_pos[0], data.y + stopper_pos[1], data.r) for _, data in pcb_data.iterrows()]
point_pos = {idx: Point(data.x + stopper_pos[0], data.y + stopper_pos[1], data.r) for idx, data in
pcb_data.iterrows()}
left_boundary, right_boundary = min(point_pos, key=lambda pt: pt.x).x, max(point_pos, key=lambda pt: pt.x).x
left_boundary, right_boundary = (min(point_pos.values(), key=lambda pt: pt.x).x,
max(point_pos.values(), key=lambda pt: pt.x).x)
search_step = max((right_boundary - left_boundary) / max_head_index, 0)
cycle_pick_pos = []
for feeder_slot in feeder_assign:
@@ -1571,7 +1575,8 @@ def select_and_apply_repair_operator(point_pos, comp_of_point, weight, solution,
@timer_wrapper
def alns_route_reschedule(pcb_data, placement_res, headseq_res, component_res, feeder_slot_res, cycle_res, hinter=True):
point_pos = [Point(data.x + stopper_pos[0], data.y + stopper_pos[1], data.r) for _, data in pcb_data.iterrows()]
point_pos = {idx: Point(data.x + stopper_pos[0], data.y + stopper_pos[1], data.r) for idx, data in
pcb_data.iterrows()}
comp_of_point = defaultdict(int)
cycle_index = 0
for cycle_group_index, cycle_group_num in enumerate(cycle_res):
@@ -1643,23 +1648,6 @@ def alns_route_reschedule(pcb_data, placement_res, headseq_res, component_res, f
# plt.plot(range(len(best_move_time_list)), best_move_time_list)
# plt.show()
print('best move time', best_move_time_list[-1])
workbook = openpyxl.load_workbook('result/alns_route.xlsx')
worksheet = workbook.active
writing_colum = None
for col in worksheet.iter_cols(min_col=0, max_col=100):
for cell in col:
if cell.value is None:
writing_colum = cell.column_letter
break
if writing_colum:
break
for row_num, value in enumerate(best_move_time_list):
cell_reference = f"{writing_colum}{row_num + 1}"
worksheet[cell_reference] = value
workbook.save('result/alns_route.xlsx')
return best_solution.placement_res, best_solution.headseq_res