基于改进遗传算法的流水车间作业调度

参考

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_NEW:
	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
		self.n = 1
	
	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 = self.pop_size
		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))  # select posibility
			p[i, 2] = np.sum(p[:i + 1, 1, 0])
		for i in range(self.n, 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.n) * self.Pc)
		index = np.random.choice(np.arange(self.n + 1, 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.n) * self.Pm)
		index = np.random.choice(np.arange(self.n, crossover.shape[0]), 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_new(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_NEW(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

你可能感兴趣的:(NPprojrcts)