gatt、makespan_value、baker、xos
# -*- coding:utf-8 -*-
import numpy as np
import time
from .tool import makespan_value
from .ga_crossover import baker, xpm
class GA_FSP:
def __init__(self, data, pop_size=50, max_gen=100, Pc=0.65, Pm=0.35):
self.data = data
self.pop_size = pop_size
self.NDA = data.shape[1]
self.max_gen = max_gen
self.Pc = Pc
self.Pm = Pm
def crtp(self):
pop = np.zeros([self.pop_size, self.NDA], dtype=int)
pop[0] = np.random.permutation(self.NDA)
for i in range(1, self.pop_size):
data_pop = np.random.permutation(self.NDA)
for k in range(i):
if (data_pop == pop[k]).all():
data_pop = np.random.permutation(self.NDA)
pop[i] = data_pop
return pop
def fitness(self, pop):
fitness = np.zeros([self.pop_size, 1])
for i in range(self.pop_size):
fitness[i] = 1 / makespan_value(self.data[:, pop[i]])
return fitness
def select(self, pop, fitness):
index = np.argsort(-fitness[:, 0])
p = np.zeros([self.pop_size, 3, self.NDA])
select = pop[index, :]
M = p.shape[0]
a, b = baker(M)
for i in range(self.pop_size):
p[i, 0] = pop[i]
p[i, 1] = (a - b * (i + 1)) / (M * (M + 1))
p[i, 2] = np.sum(p[:i + 1, 1, 0])
for i in range(self.pop_size - 1):
Pi = np.random.rand()
if p[i, 2, 0] > Pi and p[i + 1, 2, 0] < Pi:
select[i + 1] = np.array(p[i + 1, 0], dtype=int)
return select
def crossover(self, select):
n = int(self.pop_size * self.Pc)
index = np.random.choice(self.pop_size, n, replace=False)
crossover = np.copy(select)
crossover[index] = xpm(select[index])
return crossover
def mutation(self, crossover):
n = int(self.pop_size * self.Pm)
index = np.random.choice(self.pop_size, n, replace=False)
for i in range(n):
p = np.random.choice(self.NDA, 2, replace=False)
temp = np.copy(crossover[index[i], p[0]]), np.copy(crossover[index[i], p[1]])
crossover[index[i], p[0]], crossover[index[i], p[1]] = temp[1], temp[0]
return crossover
def ga_fsp(data, pop_size=50, max_gen=100, Pc=0.65, Pm=0.35, draw=222):
"""
流水车间作业调度的遗传算法
轮盘赌选、部分匹配交叉混合顺序交叉
:param data: m行n列,第1行工序编号,值加工时间
:param pop_size: 种群大小
:param max_gen: 最大进化代数
:param Pc: 交叉概率
:param Pm: 变异概率
:param draw:甘特图、适应度图、动态适应度图
:return:
"""
data = data[:, np.argsort(data[0])]
new = GA_FSP(data, pop_size, max_gen, Pc, Pm)
pop = new.crtp()
pop_trace = np.zeros([max_gen, 3])
genetic_trace = np.zeros([max_gen, data.shape[1]], dtype=int)
start_time = time.time()
for g in range(max_gen):
fitness = new.fitness(pop)
pop_trace[g] = [g, np.mean(fitness), np.max(fitness)]
genetic_trace[g] = pop[np.argmax(fitness)]
select = new.select(pop, fitness)
crossover = new.crossover(select)
pop = new.mutation(crossover)
end_time = time.time()
best_genetic = genetic_trace[np.argmax(pop_trace[:, 2])]
total_best = np.where(pop_trace[:, 2] == np.max(pop_trace[:, 2]))[0]
print("Time used:%.4f" % (end_time - start_time))
print("The first best generation:%s" % np.argmax(pop_trace[:, 2]))
print("Best generations:%s" % total_best)
print("Numbers of best generation:%s" % total_best.shape[0])
print("The minimum makespan: %s" % makespan_value(data[:, best_genetic]))
if draw != 222:
import matplotlib.pyplot as plt
from .tool import gatt
if int(str(draw)[0]) != 2:
plt.figure(1)
gatt(data[:, best_genetic])
plt.show()
if int(str(draw)[1]) != 2:
plt.figure(2)
plt.plot(pop_trace[:, 0], pop_trace[:, 2], "r-", label=r"$Best$ $fitness$")
plt.plot(pop_trace[:, 0], pop_trace[:, 1], "b-", label=r"$Pop$ $fitness$")
plt.xlabel(r"$Generation_i$")
plt.ylabel(r"$Fitness$")
plt.legend()
plt.show()
if int(str(draw)[2]) != 2:
plt.ioff()
for i in range(1, max_gen):
plt.figure(2)
plt.plot([pop_trace[i - 1, 0], pop_trace[i, 0]], [pop_trace[i - 1, 2], pop_trace[i, 2]], "r-",
label=r"$Best$ $fitness$")
plt.plot([pop_trace[i - 1, 0], pop_trace[i, 0]], [pop_trace[i - 1, 1], pop_trace[i, 1]], "b-",
label=r"$Pop$ $fitness$")
plt.xlabel(r"$Generation_i$")
plt.ylabel(r"$Fitness$")
plt.pause(0.01)
plt.show()
best_genetic += 1
return best_genetic