整线优化第一版论文定稿工程

增加了整线批量测试
修改了现有min-max模型路径
修改了遗传算法整体框架
估计器增加异常数据剔除
封装优化结果类
修改供料器扫描算法中重复吸嘴组的判定
This commit is contained in:
2024-06-26 09:44:08 +08:00
parent cbeba48da0
commit 37f4e5b02c
14 changed files with 749 additions and 669 deletions

View File

@ -33,7 +33,7 @@ def random_component_assignment(pcb_data, component_data, machine_number, estima
machine_assign = list(range(machine_number))
random.shuffle(machine_assign)
finished_assign_counter = 0
finished_assign_counter = component_points.count(0)
while finished_assign_counter < component_number:
for machine_index in machine_assign:
part = random.randint(0, component_number - 1)
@ -53,16 +53,13 @@ def random_component_assignment(pcb_data, component_data, machine_number, estima
finished_assign_counter += 1
assert sum(component_points) == 0
val = 0
if estimator:
cp_items = estimator.convert(pcb_data, component_data, assignment_result)
for machine_index in range(machine_number):
cp_points, cp_nozzle, cp_width, cp_height, board_width, board_height = cp_items[machine_index]
# objective_value.append(
# estimator.neural_network(cp_points, cp_nozzle, cp_width, cp_height, board_width, board_height))
val = max(val, estimator.heuristic(cp_points, cp_nozzle))
objective_value = 0
cp_items = converter(pcb_data, component_data, assignment_result)
for machine_index in range(machine_number):
cp_points, cp_nozzle, board_width, board_height = cp_items[machine_index]
objective_value = max(objective_value, estimator.predict(cp_points, cp_nozzle, board_width, board_height))
return val, assignment_result
return objective_value, assignment_result
def greedy_component_assignment(component_points, component_nozzle, component_feeders, task_block_weight):
@ -75,6 +72,7 @@ def local_search_component_assignment(pcb_data, component_data, machine_number,
component_number = len(component_data)
iteration_counter, unsuccessful_iteration_counter = 5000, 50
optimal_val, optimal_assignment = random_component_assignment(pcb_data, component_data, machine_number, estimator)
for _ in range(iteration_counter):
machine_idx = random.randint(0, machine_number - 1)
if sum(optimal_assignment[machine_idx]) == 0:
@ -90,7 +88,8 @@ def local_search_component_assignment(pcb_data, component_data, machine_number,
assignment = copy.deepcopy(optimal_assignment)
cyclic_counter = 0
swap_machine_idx = None
while cyclic_counter <= 2 * machine_idx:
swap_available = False
while cyclic_counter <= 2 * machine_number:
cyclic_counter += 1
swap_machine_idx = random.randint(0, machine_number - 1)
feeder_available = 0
@ -99,16 +98,18 @@ def local_search_component_assignment(pcb_data, component_data, machine_number,
feeder_available += 1
if feeder_available <= component_data.iloc[part_idx].fdn and swap_machine_idx != machine_idx:
swap_available = True
break
assert swap_machine_idx is not None
assignment[machine_idx][part_idx] -= r
assignment[swap_machine_idx][part_idx] += r
if swap_available:
assignment[machine_idx][part_idx] -= r
assignment[swap_machine_idx][part_idx] += r
val = 0
cp_items = estimator.convert(pcb_data, component_data, assignment)
cp_items = converter(pcb_data, component_data, assignment)
for machine_index in range(machine_number):
cp_points, cp_nozzle, _, _, _, _ = cp_items[machine_index]
val = max(val, estimator.heuristic(cp_points, cp_nozzle))
cp_points, cp_nozzle, board_width, board_height = cp_items[machine_index]
val = max(val, estimator.predict(cp_points, cp_nozzle, board_width, board_height))
if val < optimal_val:
optimal_assignment, optimal_val = assignment, val
@ -183,12 +184,6 @@ def reconfig_crossover_operation(component_data, parent1, parent2, machine_numbe
offspring[machine_index][part_index] += 1
additional_points -= 1
# === 结果校验 ===
for offspring in [offspring1, offspring2]:
for part in range(component_number):
pt = sum(offspring[mt][part] for mt in range(machine_number))
assert pt == component_data.iloc[part]['points']
return offspring1, offspring2
@ -205,18 +200,23 @@ def reconfig_mutation_operation(component_data, parent, machine_number):
for component_index, points in enumerate(offspring[swap_machine1]):
if points:
component_list.append(component_index)
if len(component_list) == 0:
return offspring
swap_component_index = random.sample(component_list, 1)[0]
swap_points = random.randint(1, offspring[swap_machine1][swap_component_index])
feeder_counter = 0
for machine_index in range(machine_number):
if offspring[swap_machine1][swap_component_index] < swap_points or machine_index == swap_machine2:
feeder_counter += 1
if feeder_counter > component_data.iloc[swap_component_index].fdn:
return offspring
offspring[swap_machine1][swap_component_index] -= swap_points
offspring[swap_machine2][swap_component_index] += swap_points
feeder_counter = 0
for machine_index in range(machine_number):
if offspring[machine_index][swap_component_index]:
feeder_counter += 1
if feeder_counter > component_data.iloc[swap_component_index].fdn:
return parent
return offspring
@ -229,38 +229,35 @@ def evolutionary_component_assignment(pcb_data, component_data, machine_number,
generation_number = 100
mutation_rate, crossover_rate = 0.1, 0.8
population = []
population, pop_val = [], []
for _ in range(population_size):
population.append(random_component_assignment(pcb_data, component_data, machine_number, None)[1])
population.append(random_component_assignment(pcb_data, component_data, machine_number, estimator)[1])
cp_items = converter(pcb_data, component_data, population[-1])
val = 0
for machine_index in range(machine_number):
cp_points, cp_nozzle, board_width, board_height = cp_items[machine_index]
val = max(val, estimator.predict(cp_points, cp_nozzle, board_width, board_height))
pop_val.append(val)
with tqdm(total=generation_number) as pbar:
pbar.set_description('evolutionary algorithm process for PCB assembly line balance')
new_population = []
for _ in range(generation_number):
population += new_population
# calculate fitness value
pop_val = []
for individual in population:
for individual in new_population:
val = 0
cp_items = estimator.convert(pcb_data, component_data, individual)
cp_items = converter(pcb_data, component_data, individual)
for machine_index in range(machine_number):
cp_points, cp_nozzle, _, _, _, _ = cp_items[machine_index]
val = max(val, estimator.heuristic(cp_points, cp_nozzle))
cp_points, cp_nozzle, board_width, board_height = cp_items[machine_index]
val = max(val, estimator.predict(cp_points, cp_nozzle, board_width, board_height))
pop_val.append(val)
select_index = get_top_k_value(pop_val, population_size - len(new_population), reverse=False)
select_index = get_top_k_value(pop_val, population_size, reverse=False)
population = [population[idx] for idx in select_index]
pop_val = [pop_val[idx] for idx in select_index]
population += new_population
for individual in new_population:
cp_items = estimator.convert(pcb_data, component_data, individual)
val = 0
for machine_index in range(machine_index):
cp_points, cp_nozzle, _, _, _, _ = cp_items[machine_index]
val = max(val, estimator.heuristic(cp_points, cp_nozzle))
pop_val.append(val)
# min-max convert
max_val = max(pop_val)
pop_val_sel = list(map(lambda v: max_val - v, pop_val))
@ -298,11 +295,12 @@ def evolutionary_component_assignment(pcb_data, component_data, machine_number,
def line_optimizer_reconfiguration(component_data, pcb_data, machine_number):
# === assignment of heads to modules is omitted ===
optimal_assignment, optimal_val = [], None
estimator = RegressionEstimator() # element from list [0, 1, 2, 5, 10] task_block ~= cycle
estimator = ReconfigEstimator() # element from list [0, 1, 2, 5, 10] task_block ~= cycle
# === assignment of components to heads
for i in range(5):
if i == 0:
# random
print('random component allocation algorithm process for PCB assembly line balance')
val, assignment = random_component_assignment(pcb_data, component_data, machine_number, estimator)
elif i == 1:
# brute force
@ -310,6 +308,7 @@ def line_optimizer_reconfiguration(component_data, pcb_data, machine_number):
continue
elif i == 2:
# local search
print('local search component allocation algorithm process for PCB assembly line balance')
val, assignment = local_search_component_assignment(pcb_data, component_data, machine_number, estimator)
elif i == 3:
# evolutionary