FJSP-GA/GA.py

152 lines
4.9 KiB
Python

import itertools
import random
import numpy as np
from Decode import Decode
from Instance import *
class GA():
def __init__(self):
self.Pop_size = 400 # 种群数量
self.Pc = 0.8 # 交叉概率
self.Pm = 0.3 # 变异概率
self.Pv = 0.5 # 选择何种方式进行交叉的概率阈值
self.Pw = 0.95 # 选择何种方式进行变异的概率阈值
self.Max_Itertions = 100 # 最大迭代次数
# 适应度
def fitness(self, CHS, J, Processing_time, M_num, Len):
Fit = []
for i in range(len(CHS)):
d = Decode(J, Processing_time, M_num)
Fit.append(d.decode(CHS[i], Len))
return Fit
# 机器部分交叉
def machine_cross(self, CHS1, CHS2, T0):
"""
:param CHS1: 机器选择部分的基因1
:param CHS2: 机器选择部分的基因2
:param T0: 工序总数
:return: 交叉后的机器选择部分的基因
"""
T_r = [j for j in range(T0)]
r = random.randint(1, 10) # 在区间[1,T0]内产生一个整数r
random.shuffle(T_r)
R = T_r[0:r] # 按照随机数r产生r个互不相等的整数
OS_1 = CHS1[O_num:2 * T0]
OS_2 = CHS2[O_num:2 * T0]
MS_1 = CHS2[0:T0]
MS_2 = CHS1[0:T0]
for i in R:
K, K_2 = MS_1[i], MS_2[i]
MS_1[i], MS_2[i] = K_2, K
CHS1 = np.hstack((MS_1, OS_1))
CHS2 = np.hstack((MS_2, OS_2))
return CHS1, CHS2
# 工序部分交叉
def operation_cross(self, CHS1, CHS2, T0, J_num):
"""
:param CHS1: 工序选择部分的基因1
:param CHS2: 工序选择部分的基因2
:param T0: 工序总数
:param J_num: 工件总数
:return: 交叉后的工序选择部分的基因
"""
OS_1 = CHS1[T0:2 * T0]
OS_2 = CHS2[T0:2 * T0]
MS_1 = CHS1[0:T0]
MS_2 = CHS2[0:T0]
Job_list = [i for i in range(J_num)]
random.shuffle(Job_list)
r = random.randint(1, J_num - 1)
Set1 = Job_list[0:r]
new_os = list(np.zeros(T0, dtype=int))
for k, v in enumerate(OS_1):
if v in Set1:
new_os[k] = v + 1
for i in OS_2:
if i not in Set1:
Site = new_os.index(0)
new_os[Site] = i + 1
new_os = np.array([j - 1 for j in new_os])
CHS1 = np.hstack((MS_1, new_os))
CHS2 = np.hstack((MS_2, new_os))
return CHS1, CHS2
# 机器部分变异
def machine_variation(self, CHS, O, T0, J):
"""
:param CHS: 机器选择部分的基因
:param O: 加工时间矩阵
:param T0: 工序总数
:param J: 各工件加工信息
:return: 变异后的机器选择部分的基因
"""
Tr = [i_num for i_num in range(T0)]
MS = CHS[0:T0]
OS = CHS[T0:2 * T0]
# 机器选择部分
r = random.randint(1, T0 - 1) # 在变异染色体中选择r个位置
random.shuffle(Tr)
T_r = Tr[0:r]
for num in T_r:
T_0 = [j for j in range(T0)]
K = []
Site = 0
for k, v in J.items():
K.append(T_0[Site:Site + v])
Site += v
for i in range(len(K)):
if num in K[i]:
O_i = i
O_j = K[i].index(num)
break
Machine_using = O[O_i][O_j]
Machine_time = []
for j in Machine_using:
if j != 9999:
Machine_time.append(j)
Min_index = Machine_time.index(min(Machine_time))
MS[num] = Min_index
CHS = np.hstack((MS, OS))
return CHS
# 工序部分变异
def operation_variation(self, CHS, T0, J_num, J, O, M_num):
"""
:param CHS: 工序选择部分的基因
:param T0: 工序总数
:param J_num: 工件总数
:param J: 各工件加工信息
:param O: 加工时间矩阵
:param M_num: 机器总数
:return: 变异后的工序选择部分的基因
"""
MS = CHS[0:T0]
OS = list(CHS[T0:2 * T0])
r = random.randint(1, J_num - 1)
Tr = [i for i in range(J_num)]
random.shuffle(Tr)
Tr = Tr[0:r]
J_os = dict(enumerate(OS)) # 随机选择r个不同的基因
J_os = sorted(J_os.items(), key=lambda d: d[1])
Site = []
for i in range(r):
Site.append(OS.index(Tr[i]))
A = list(itertools.permutations(Tr, r))
A_CHS = []
for i in range(len(A)):
for j in range(len(A[i])):
OS[Site[j]] = A[i][j]
C_I = np.hstack((MS, OS))
A_CHS.append(C_I)
Fit = []
for i in range(len(A_CHS)):
d = Decode(J, O, M_num)
Fit.append(d.decode(CHS, T0))
return A_CHS[Fit.index(min(Fit))]