1 Star 1 Fork 0

独一无二/遗传算法货位优化

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
GA货位优化.py 7.04 KB
一键复制 编辑 原始数据 按行查看 历史
独一无二 提交于 2023-05-16 08:57 . main
import random
from xlwt import Workbook
from matplotlib import pyplot as plt
from pandas import read_excel, DataFrame
from numpy import zeros, array, arange, hstack
from numpy.random import choice, rand, randint
excel = read_excel('基础数据表.xls')
Q = [_ for _ in list(excel['出库频次']) if _ != NaN]
K = [_ for _ in list(excel['货物品类编号']) if _ != NaN]
M = [_ for _ in list(excel['货物重量']) if _ != NaN]
a, h, c, g, miu, A, B, C, w1, w2, q_ = list(excel['模型参数'][:11])
# 货格长度、货位高度、通道宽度、重力加速度、地面摩擦系数、x方向有A排、y方向有B列、z方向有C层、第一个规则的权值、第二个规则的权值
epochs, n_variables, cross_rate, mutate_rate = list(excel['算法参数'][:4])
n_goods, goods = len(K), [] # 货物的数量
A, B, C, epochs, n_variables = int(A), int(B), int(C), int(epochs), int(n_variables) # 取整数
class Goods: # 商品类
def __init__(self, i, x, y, z, k, m, q):
self.i = i # 编号
self.x = x # 排数
self.y = y # 列数
self.z = z # 层数
self.k = k # 种类
self.m = m # 质量
self.q = q # 频率
self.mid_x = 0 # 这类商品的中心x坐标
self.mid_y = 0 # 这类商品的中心y坐标
self.mid_z = 0 # 这类商品的中心z坐标
def get(self):
return [self.i, self.x, self.y, self.z, self.k, self.m, self.q, self.mid_x, self.mid_y, self.mid_z]
class GA:
def __init__(self, m, n, func):
code = [] # 生成初始种群
nums = zeros((m, 3 * n))
coo = zeros((m, n, 3)) # 以坐标的形式展现出来
for i in range(m):
for j in range(n):
code.append(random.sample(range(0, A * B * C), n))
code = array(code)
for i in range(m):
for j in range(n):
nums[i, j + n] = code[i, j] // (A * C)
copy = nums[i, j + n]
nums[i, j + 2 * n] = (code[i, j] - copy * (A * C)) // A
cop = nums[i, j + 2 * n]
nums[i, j] = code[i, j] - cop * A - copy * A * C
coo[i, j] = [nums[i, j], nums[i, j + n], nums[i, j + 2 * n]]
nums = array(nums)
m = nums.shape[0]
n = nums.shape[1]
pop = zeros((m, n // 3))
for i in range(m):
for j in range(n // 3): # 编码方式:
pop[i, j] = nums[i, j] + nums[i, j + n // 3] * A * C + nums[i, j + 2 * n // 3] * A
self.POP = pop
self.cross_rate = cross_rate
self.mutation = mutate_rate
self.func = func
self.h = []
def translate_dna(self): # 将编码后的DNA翻译回来(解码)
pop = self.POP
m = pop.shape[0]
n = pop.shape[1]
vector = zeros((m, 3 * n))
for i in range(m):
for j in range(n):
vector[i, j + n] = pop[i, j] // (A * C)
copy = vector[i, j + n]
vector[i, j + 2 * n] = (pop[i, j] - copy * (A * C)) // A
cop = vector[i, j + 2 * n]
vector[i, j] = pop[i, j] - cop * A - copy * A * C
return vector
def get_fitness(self): # 得到适应度
return q_ / self.func(self.translate_dna())
def select(self): # 自然选择
fitness = self.get_fitness()[0]
self.POP = self.POP[
choice(arange(self.POP.shape[0]), size=self.POP.shape[0], replace=True, p=fitness / sum(fitness))]
def crossover(self): # 染色体交叉
for people in self.POP:
if rand() < self.cross_rate:
i_ = randint(0, self.POP.shape[0], size=1)
dd = randint(0, len(people), size=randint(0, len(people)))
for d in dd:
if self.POP[i_, d] not in people:
people[d] = self.POP[i_, d]
def mutate(self): # 基因变异
for people in self.POP:
for point in range(len(people)):
if rand() < self.mutation:
x = randint(0, A * B * C)
people[point] = x if x not in people else people[point]
def evolution(self): # 进化
self.select()
self.crossover()
self.mutate()
def log(self): # 打印当前状态日志
d1 = self.translate_dna()
d2 = self.get_fitness().reshape((len(self.POP), 1))
d3 = hstack((d1, d2))
return DataFrame(d3)
def out(all_goods): # 输出为excel
book = Workbook(encoding='utf-8')
worksheet = book.add_sheet('结果')
sheet = [
['货物编号', '排', '列', '层', '货物品类编号', '货物重量', '出库频次', '该类中心x', '该类中心y', '该类中心z']]
for good in all_goods:
sheet.append(good.get())
for line in range(len(sheet)):
for row in range(len(sheet[0])):
worksheet.write(line, row, sheet[line][row])
book.save('货位分配结果表.xls')
print('已保存 货位分配结果表.xls')
def show(history):
plt.plot([i for i in range(len(history))], history)
plt.xlabel('epoch')
plt.ylabel('value')
plt.savefig('迭代优化图.png')
plt.show()
print('已保存 迭代优化图.png')
def aim_function(matrix):
global goods
values = []
for xyz in matrix:
goods = [Goods(i=j + 1, x=xyz[j] + 1, y=xyz[j + n_goods] + 1, z=xyz[j + 2 * n_goods] + 1,
k=K[j], m=M[j], q=Q[j]) for j in range(n_goods)]
w_0 = sum([good.m * g * good.q * miu * ((good.x / 2 - 1) * (2 * a + c) + a + c / 2) for good in goods])
w_1 = sum([good.m * g * good.q * ((good.z - 1) * h) for good in goods])
w_ = w_0 + w_1
for class_num in range(len(set(good.k for good in goods))):
x = sum([good.x for good in goods if good.k == class_num])
y = sum([good.y for good in goods if good.k == class_num])
z = sum([good.z for good in goods if good.k == class_num])
n = sum([1 for good in goods if good.k == class_num])
for good in goods:
if good.k == class_num:
good.mid_x, good.mid_y, good.mid_z = x / n, y / n, z / n
d_ = sum([((good.mid_x - good.x) ** 2 + (good.mid_y - good.y) ** 2 + (good.mid_z - good.z) ** 2) ** (1 / 2)
for good in goods])
values.append(w1 * w_ + w2 * d_)
return array([values])
ga = GA(m=n_variables, n=n_goods, func=aim_function)
for epoch in range(epochs):
ga.evolution()
res = array(ga.log())
rs = aim_function(res).tolist()[0]
value = max(rs)
index = rs.index(value)
if len(ga.h) > 0:
value = value if value < min(ga.h) else min(ga.h)
ga.h.append(value)
res = res[index]
print(f'轮次:{epoch + 1}/{epochs} 最优解:{value}')
result = [[int(o) for o in [res[one], res[one + n_goods], res[one + n_goods * 2]]] for one in range(n_goods)]
out(all_goods=goods)
show(ga.h)
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Python
1
https://gitee.com/wanglidong666/GA.git
git@gitee.com:wanglidong666/GA.git
wanglidong666
GA
遗传算法货位优化
WLD

搜索帮助

0d507c66 1850385 C8b1a773 1850385