调整工程架构,增补了几种算法,初步添加神经网路训练拟合代码
This commit is contained in:
@ -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
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user