import copy
import numpy as np
import random
class Node:
def __init__(self,data,fitness):
self.data = data
self.fitness = fitness
#种群条件数据
init_data = [[1,31,41,25,30],
[2,19,55,3,34],
[3,23,42,27,6],
[4,13,22,14,13],
[5,33,5,57,19]]
init_data = np.array(init_data)
#基本数据
source_data = {'1':[1,31,41,25,30],
'2':[2,19,55,3,34],
'3':[3,23,42,27,6],
'4':[4,13,22,14,13],
'5':[5,33,5,57,19]
}
#初始化种群
#order_list:初始化种群时的顺序,后期可以调为随机。
order_list1 = [4,2,5,1,3]
class GA_FSP:
def __init__(self,pc=0.6,pm=0.1,N=20,T=50,n=5,machine=4):
'''
N = 20 #群体大小
T = 50 #Ga终止进化代数
Pc = 0.6 #交叉概率
Pm=0.1 #变异概率
n = 5 #工件个数
machine = 4 #机器个数
'''
# self.data = data
self.pc = pc
self.pm = pm
self.N = N
self.T = T
self.n = n
self.machine = machine
def fitness(self,order_list):
'''
输入状态数据,即可输出适应度和加工时间
'''
def init_group(order_list):
'''
根据列表顺序调整整体数据。
'''
three_init_data = copy.deepcopy(order_list)
# print(three_init_data)
for j in range(len(order_list)):
i = order_list[j]
order_i = str(i)
init_i = i-1
three_init_data[j] = source_data[order_i]
init_group = np.array(three_init_data)
return init_group
init_data = init_group(order_list)
# k为加工工件数量
# j为机器数量
k = init_data.shape[0]
j = init_data.shape[1]-1
def find_time(k,j):
if k==1 and j==1:
return init_data[0,1]
elif k>=2 and j==1:
return find_time(k-1,1)+init_data[k-1,1]
elif k == 1 and j>=2:
return find_time(1,j-1)+init_data[0,j]
else:
time = max(find_time(k-1,j),find_time(k,j-1))+init_data[k-1,j]
return time
time = find_time(k,j)
fitness = 1/time
return fitness,time
def init_list(self,N):
N_group = []
for i in range(N):
order_list = [p for p in range(1,self.n+1)]
random.shuffle(order_list)
# node = Node(order_list,fitness(order_list))
N_group.append(order_list)
return N_group
def where_change(self,three_change_list):
for i in range(len(three_change_list)):
if three_change_list[i]<=0:
return i
continue
def cross_change(self,choice_three):
changed_list = []
'''
函数:两点交叉 传入数据为node列表 长度20
'''
def change_main(a1,a2):
'''
两点交叉
传入数据为两个个体
'''
# print("两个父类")
# print(a1.data)
# print(a2.data)
a1_copy = copy.deepcopy(a1)
a2_copy = copy.deepcopy(a2)
random_1=random.randint(0,self.n-1)
random_2=random.randint(0,self.n-1)
while random_1 > random_2 or random_1 == random_2:
random_1 = random.randint(0,self.n-1)
random_2 = random.randint(0,self.n-1)
a1_copy.data[random_1:random_2],a2_copy.data[random_1:random_2]=a2_copy.data[random_1:random_2],a1_copy.data[random_1:random_2]
intermediate1 = a1.data[random_1:random_2]
intermediate2 = a2.data[random_1:random_2]
# print("两个随机数")
# print(random_1)
# print(random_2)
head1 = []
head2 = []
tail1 = []
tail2 = []
# 子代1头
# print("head1")
for i in a1_copy.data[:random_1]:
# print(i)
while i in intermediate2:
i = intermediate1[intermediate2.index(i)]
head1.append(i)
# 子代1尾
# print("tail1")
for i in a1_copy.data[random_2:]:
while i in intermediate2:
i = intermediate1[intermediate2.index(i)]
tail1.append(i)
# 子代2头
# print("head2")
for i in a2_copy.data[:random_1]:
while i in intermediate1:
i = intermediate2[intermediate1.index(i)]
head2.append(i)
# 子代2尾
# print("tail2")
for i in a2_copy.data[random_2:]:
while i in intermediate1:
i = intermediate2[intermediate1.index(i)]
tail2.append(i)
result1 = head1 + intermediate2 + tail1
result2 = head2 + intermediate1 + tail2
# print("两个子类")
# print(result1)
# print(result2)
result1 = Node(result1,self.fitness(result1))
result2 = Node(result2,self.fitness(result2))
return result1,result2
male = choice_three[0:len(choice_three):2]
female = choice_three[1:len(choice_three):2]
if len(male) != len(female):
minmale = min(len(male),len(female))
else:
minmale = len(male)
for j in range(minmale):
cross_rand = random.random()
if cross_rand
a1,a2 = change_main(male[j],female[j])
changed_list.append(a1)
changed_list.append(a2)
else:
changed_list.append(male[j])
changed_list.append(female[j])
# print(changed_list)
return changed_list
def variation_change(self,cross_change_three):
changed_variation=[]
for j in range(len(cross_change_three)):
variation_rand = random.random()
if variation_rand
random_1=random.randint(0,self.n-1)
random_2=random.randint(0,self.n-1)
# print("变异之前的数据",cross_change_three[j].data)
cross_change_three[j].data[random_1],cross_change_three[j].data[random_2]=cross_change_three[j].data[random_2],cross_change_three[j].data[random_1]
changed_variation.append(cross_change_three[j])
# print("变异之后的数据",cross_change_three[j].data)
else:
changed_variation.append(cross_change_three[j])
return changed_variation
def __sort_threelist(self,arr):
'''
冒泡排序
'''
n = len(arr)
for i in range(n):
for j in range(0,n-i-1):
if arr[j].fitness[1]>arr[j+1].fitness[1]:
arr[j],arr[j+1] = arr[j+1] ,arr[j]
return arr
def pro_go(self):
#初始化种群
N_group = self.init_list(self.N)
for j in range(len(N_group)):
N_group[j] = Node(N_group[j],self.fitness(N_group[j]))
#开始迭代
draw_x = []
draw_y = []
for num in range(self.T+1):
#计算适应度
for j in range(len(N_group)):
N_group[j].fitness = self.fitness(N_group[j].data)
# print(N_group[j].fitness[0])
# print(N_group)
if num>self.T:
break
#选择操作
choiceList = [N_group[i].fitness[1] for i in range(len(N_group))]
# print(choiceList)
'''
求出个体i被选中的概率
'''
choice = copy.deepcopy(choiceList)
choice = [choiceList[j]/sum(choiceList) for j in range(len(choiceList))]
# print(choice)
sum_choice = []
for p in range(len(choice)):
if p == 0 :
sum_choice.append(choice[p])
else:
sum_choice.append(choice[p] + sum_choice[p-1])
# print(sum_choice)
# print(rand_num)
'''
选数 原先列表有几行就要选出几个
'''
choice_three = []
for i in range(self.N):
rand_num = random.random()
three_change_list = [rand_num-sum_choice[i] for i in range(len(sum_choice))]
change_index = self.where_change(three_change_list)
choice_three.append(N_group[change_index])
'''
交叉
传入种群节点即可
'''
cross_choice_three = self.cross_change(choice_three)
# print(choice_three)
'''
变异
'''
variation_three = self.variation_change(cross_choice_three)
sort_group= N_group+variation_three
print("第"+str(num)+"次迭代",end=" ")
N_group = self.__sort_threelist(sort_group)[0:self.N]
print(N_group[0].fitness[1],end='--')
print(N_group[-1].fitness[1])
# print()
draw_x.append(num)
draw_y.append(N_group[0].fitness[1])
random.shuffle(N_group)
N_group = self.__sort_threelist(sort_group)[0:self.N]
for i in range(len(N_group)):
print(N_group[i].data)
return N_group[i],draw_x,draw_y
Ga1 = GA_FSP()
best1,draw_x,draw_y = Ga1.pro_go()
final_data = best1.data
import matplotlib.pyplot as plt
plt.plot(draw_x, draw_y)
plt.show()