调整工程架构,增补了几种算法,初步添加神经网路训练拟合代码

This commit is contained in:
2024-03-29 22:10:07 +08:00
parent 800057e000
commit bae7e4e2c3
18 changed files with 2459 additions and 354 deletions

View File

@ -1,25 +1,22 @@
import copy
import time
import math
import random
import argparse
import os
import warnings
import copy
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from functools import wraps
from collections import defaultdict
from tqdm import tqdm
from gurobipy import *
from sklearn.linear_model import LinearRegression
# 整线参数
max_machine_index = 3
# 时间参数
T_pp, T_tr, T_nc, T_pl = 2, 5, 25, 0
import os
import time
import math
import random
import copy
import torch
import argparse
import joblib
import pickle
import warnings
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 机器参数
max_head_index, max_slot_index = 6, 120
@ -56,6 +53,73 @@ t_nozzle_put, t_nozzle_pick = 0.9, 0.75 # 装卸吸嘴用时
t_nozzle_change = t_nozzle_put + t_nozzle_pick
t_fix_camera_check = 0.12 # 固定相机检测时间
# 时间参数(整线相关)
T_pp, T_tr, T_nc, T_pl = 2, 5, 25, 0
class OptInfo:
def __init__(self):
self.placement_time = 0
self.cycle_counter = 0
self.nozzle_change_counter = 0
self.pickup_counter = 0
self.pickup_movement = 0
self.placement_movement = 0
def optimization_assign_result(component_data, pcb_data, component_result, cycle_result, feeder_slot_result,
nozzle_hinter=False, component_hinter=False, feeder_hinter=False):
if nozzle_hinter:
columns = ['H{}'.format(i + 1) for i in range(max_head_index)] + ['cycle']
nozzle_assign = pd.DataFrame(columns=columns)
for cycle, components in enumerate(component_result):
nozzle_assign.loc[cycle, 'cycle'] = cycle_result[cycle]
for head in range(max_head_index):
index = component_result[cycle][head]
if index == -1:
nozzle_assign.loc[cycle, 'H{}'.format(head + 1)] = ''
else:
nozzle_assign.loc[cycle, 'H{}'.format(head + 1)] = component_data.loc[index].nz
print(nozzle_assign)
print('')
if component_hinter:
columns = ['H{}'.format(i + 1) for i in range(max_head_index)] + ['cycle']
component_assign = pd.DataFrame(columns=columns)
for cycle, components in enumerate(component_result):
component_assign.loc[cycle, 'cycle'] = cycle_result[cycle]
for head in range(max_head_index):
index = component_result[cycle][head]
if index == -1:
component_assign.loc[cycle, 'H{}'.format(head + 1)] = ''
else:
component_assign.loc[cycle, 'H{}'.format(head + 1)] = component_data.loc[index].part
print(component_assign)
print('')
if feeder_hinter:
columns = ['H{}'.format(i + 1) for i in range(max_head_index)] + ['cycle']
feedr_assign = pd.DataFrame(columns=columns)
for cycle, components in enumerate(feeder_slot_result):
feedr_assign.loc[cycle, 'cycle'] = cycle_result[cycle]
for head in range(max_head_index):
slot = feeder_slot_result[cycle][head]
if slot == -1:
feedr_assign.loc[cycle, 'H{}'.format(head + 1)] = 'A'
else:
feedr_assign.loc[cycle, 'H{}'.format(head + 1)] = 'F{}'.format(
slot) if slot <= max_slot_index // 2 else 'R{}'.format(slot - max_head_index)
print(feedr_assign)
print('')
def axis_moving_time(distance, axis=0):
distance = abs(distance) * 1e-3
@ -315,8 +379,8 @@ def dynamic_programming_cycle_path(pcb_data, cycle_placement, assigned_feeder):
print(assigned_feeder)
print(cycle_placement)
pos.append([pcb_data.loc[placement]['x'] - head * head_interval + stopper_pos[0],
pcb_data.loc[placement]['y'] + stopper_pos[1]])
pos.append([pcb_data.iloc[placement]['x'] - head * head_interval + stopper_pos[0],
pcb_data.iloc[placement]['y'] + stopper_pos[1]])
feeder_set.add(feeder - head * interval_ratio)
@ -369,8 +433,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.loc[cycle_placement[start_head]]['x'] - start_head * head_interval > \
pcb_data.loc[cycle_placement[end_head]]['x'] - end_head * head_interval:
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:
head_sequence = list(reversed(head_sequence))
return head_sequence
@ -382,11 +446,11 @@ def greedy_placement_route_generation(component_data, pcb_data, component_result
mount_point_pos = [[] for _ in range(len(component_data))]
for i in range(len(pcb_data)):
part = pcb_data.loc[i]['part']
part = pcb_data.iloc[i]['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.loc[i]['x'], pcb_data.loc[i]['y']])
mount_point_pos[component_index].append([pcb_data.iloc[i]['x'], pcb_data.iloc[i]['y']])
search_dir = 1 # 0自左向右搜索 1自右向左搜索
for cycle_set in range(len(component_result)):
@ -883,18 +947,18 @@ def swap_mutation(parent):
return parent
def constraint_swap_mutation(component_points, individual):
def constraint_swap_mutation(component_points, individual, machine_number):
offspring = individual.copy()
idx, component_index = 0, random.randint(0, len(component_points) - 1)
for _, points in component_points:
if component_index == 0:
while True:
index1, index2 = random.sample(range(points + max_machine_index - 2), 2)
index1, index2 = random.sample(range(points + machine_number - 2), 2)
if offspring[idx + index1] != offspring[idx + index2]:
break
clip = offspring[idx: idx + points + max_machine_index - 1].copy()
clip = offspring[idx: idx + points + machine_number - 1].copy()
avl_machine = 0
for idx_, gene in enumerate(clip):
if gene == 0 and (idx_ == 0 or clip[idx_ - 1] != 0):
@ -912,7 +976,7 @@ def constraint_swap_mutation(component_points, individual):
break
component_index -= 1
idx += (points + max_machine_index - 1)
idx += (points + machine_number - 1)
return offspring
@ -959,3 +1023,92 @@ def get_top_k_value(pop_val, k: int, reverse=True):
res.append(j)
break
return res
def get_line_config_number(machine_number, component_number):
div_counter = 0
div_set = set()
for div1 in range(component_number - 2):
for div2 in range(div1 + 1, component_number - 1):
machine_div = [div1 + 1, div2 - div1, component_number - div2 - 1]
machine_div.sort()
div_str = "".join(str(s) + '|' for s in machine_div)
if div_str in div_set:
continue
div_set.add(div_str)
assign_component_counter = defaultdict(list)
for div in machine_div:
assign_component_counter[div] += 1
case_div_counter, case_comp_number = 1, component_number
for idx in range(machine_number - 1):
div = 1
while machine_div[idx]:
div *= (case_comp_number / machine_div[idx])
case_comp_number -= 1
machine_div[idx] -= 1
case_div_counter *= div
for key, val in assign_component_counter.values():
div = 1
while val:
div *= val
val -= 1
case_div_counter /= div
div_counter += case_div_counter
return div_counter
def partial_data_convert(pcb_data, component_data, machine_assign, machine_number):
assignment_result = copy.deepcopy(machine_assign)
partial_pcb_data, partial_component_data = defaultdict(pd.DataFrame), defaultdict(pd.DataFrame)
for machine_index in range(machine_number):
partial_pcb_data[machine_index] = pd.DataFrame(columns=pcb_data.columns)
partial_component_data[machine_index] = component_data.copy(deep=True)
# === averagely assign available feeder ===
for part_index, data in component_data.iterrows():
feeder_limit = data['feeder-limit']
feeder_points = [assignment_result[machine_index][part_index] for machine_index in range(max_machine_index)]
for machine_index in range(machine_number):
if feeder_points[machine_index] == 0:
continue
arg_feeder = max(math.floor(feeder_points[machine_index] / sum(feeder_points) * data['feeder-limit']), 1)
partial_component_data[machine_index].loc[part_index]['feeder-limit'] = arg_feeder
feeder_limit -= arg_feeder
for machine_index in range(machine_number):
if feeder_limit <= 0:
break
if feeder_points[machine_index] == 0:
continue
partial_component_data[machine_index].loc[part_index]['feeder-limit'] += 1
feeder_limit -= 1
for machine_index in range(machine_number):
if feeder_points[machine_index] > 0:
assert partial_component_data[machine_index].loc[part_index]['feeder-limit'] > 0
# === assign placements ===
component_machine_index = [0 for _ in range(len(component_data))]
for _, data in pcb_data.iterrows():
part_index = component_data[component_data['part'] == data['part']].index.tolist()[0]
while True:
machine_index = component_machine_index[part_index]
if assignment_result[machine_index][part_index] == 0:
component_machine_index[part_index] += 1
machine_index += 1
else:
break
assignment_result[machine_index][part_index] -= 1
partial_pcb_data[machine_index] = pd.concat([partial_pcb_data[machine_index], pd.DataFrame(data).T])
return partial_pcb_data, partial_component_data