随机染色体突变在整个人群中是相同的
Posted
技术标签:
【中文标题】随机染色体突变在整个人群中是相同的【英文标题】:Random chromosome mutation is the same in the entire population 【发布时间】:2022-01-22 04:38:23 【问题描述】:在我的通用生产计划问题的遗传算法中,我试图使染色体内的基因发生突变。染色体是问题的时间表(解决方案),基因是时间表中一项任务的分配(子解决方案)。由于这种编码,问题与常规 GA 略有不同。染色体看起来像这样:[[gene],[gene],...]
,基因看起来像这样:[job_ID,stage_ID,Order_ID,duration,machine_ID]
。因此,它很快就变成了一长串列表。
当问题被编码到染色体中基因列表的列表中时,随机父母(随机染色体)被选择用于机器编号的突变。
在突变函数中,基因组的第五个条目(机器ID)根据可用机器更改为当前生产阶段(基因组的第二个条目)。
问题出现在输出中。在每条染色体中,相同的基因已因我的突变而改变,而预期对于每条染色体来说,这些改变都是随机的。因此,例如,在每个解决方案/时间表(染色体)中,第四、第五和第十六条染色体都发生了突变,而不是不同染色体之间的不同突变。
当我打印基因突变(每个父染色体 1 个 = 4 和 4 个突变。所以总共 16 个)时,随机性似乎是正确的。因此,我怀疑染色体或父母的变量分配存在错误。不幸的是,在 *** 和类似网站上进行了大量试验和搜索后,我没有设法找到解决方案。
提前感谢您! 抱歉问了这么长的问题。
import random
import numpy as np
def encoding(jobs, stages, machines, P_ilj):
chromosomes = []
chromosome = []
i = 1
for n in range(n_chromosomes):
while i < 4:
for j in jobs: # Initial solution: Each stage is linked to a machine available in that stage.
if i == 1:
l = 1
elif i == 2:
l = 3
else:
l = 5
# [job,stage,Order_ID,duration,machine_ID]
gene = [j, i, np.random.rand(), P_ilj[i][l][j], l]
chromosome.append(gene)
i += 1
chromosomes.append(chromosome)
return chromosomes
def parent_selection(chromosomes, n_parents):
parents = []
# Sample n parents from all chromosomes
chromosome_id = random.sample(range(len(chromosomes)), n_parents)
for parent in chromosome_id:
parents.append(chromosomes[parent])
return parents
def mutation(parents, n_mutations): # Returns literally the same changes. Should return random
# changes. The genes have the same changes for all chromosomes.
# Random machine assignment
for c, chromosome in enumerate(parents):
for gene in random.sample(range(len(chromosome)), n_mutations):
# If the stage = 1, mutate by choosing a random processing machine.
if chromosome[gene][1] == 1:
chromosome[gene][4] = int(
np.array(random.sample(proc_machs, 1)).astype(int))
elif chromosome[gene][1] == 2:
chromosome[gene][4] = int(
np.array(random.sample(buff_machs, 1)).astype(int))
else:
chromosome[gene][4] = int(
np.array(random.sample(pack_machs, 1)).astype(int))
parents[c] = chromosome
# This function malfunctions. I.e. the last loop might overwrite all chromosomes, instead of only the last parent-chromosome.
return parents
# %% Set creation
G = 10
F = 3
M1 = 2 # 28
M2 = M1
M3 = 1 # 29
T = 60*24*1 # 60*24*7
JOBS = np.arange(1, G+1)
STAGES = np.arange(1, F+1)
MACHS_R = np.arange(1, M1+1)
BUFFERS = np.arange(M1+1, M1+M2+1)
MACHS_P = np.arange(M1+M2+1, M1+M2+M3+1)
MACHS = np.arange(1, M1+M2+M3+1)
TIMES = np.arange(0, T)
# %% Sets in lists
jobs = [j for j in JOBS]
stages = [i for i in STAGES]
machines = [int(l) for l in MACHS]
proc_machs = [int(l) for l in MACHS_R]
buff_machs = [int(l) for l in BUFFERS]
pack_machs = [int(l) for l in MACHS_P]
times = [t for t in TIMES]
# %% Parameters
np.random.seed(42)
random.seed(42)
j_d, j_m_d, P_ilj = , ,
for k in stages:
for e in machines:
for y in jobs:
j_d[y] = round(np.random.rand()*10)
j_m_d[e] = j_d.copy()
# Processing time of job j on machine l in stage i.
P_ilj[k] = j_m_d.copy()
# %% DATA generation
n_parents, n_mutations, n_chromosomes = 4, 4, 8
chromosomes = encoding(jobs, stages, machines, P_ilj)
parents = parent_selection(chromosomes, n_parents)
mutated_children = mutation(parents, n_mutations)
【问题讨论】:
您的代码无法执行,我对其进行了编辑。请确保其格式正确。请检查您是否故意忽略编码中的参数阶段和机器。 这很奇怪。对我来说它做到了!它与我代表它的顺序有什么关系吗? 关于阶段:我现在看到它确实是多余的。谢谢! 【参考方案1】:在encoding
中,您只进入while
循环一次,chromosomes.append(chromosome)
将相同的染色体附加到染色体上。当您修改其中任何一个时,假设chromosomes[0][0][0]
为 1,然后通过为其分配一个新值来修改它,例如chromosomes[0][0][0] = 2
,那么不仅chromosomes[0]
,其他所有元素也会发生变化,它们的[0][0]
元素也将是2。Python不会复制chromosome
,它只是链接到同一个对象。为了避免这种情况,对于make a copy,您必须告诉python 这样做。由于您有一个列表列表,因此您必须创建一个deep copy。
# other imports
import copy
def encoding(jobs, P_ilj):
chromosomes = []
chromosome = []
i = 1
for n in range(n_chromosomes):
while i < 4:
for j in jobs: # Initial solution: Each stage is linked to a machine available in that stage.
if i == 1:
l = 1
elif i == 2:
l = 3
else:
l = 5
# [job,stage,Order_ID,duration,machine_ID]
gene = [j, i, np.random.rand(), P_ilj[i][l][j], l]
chromosome.append(gene)
i += 1
chromosomes.append(copy.deepcopy(chromosome))
return chromosomes
# other part of the code
【讨论】:
谢谢丹尼尔!这行得通。你真的帮了我大忙。我不知道我是否能够自己解决这个问题。如果可以的话,我会支持你:) 您仍然可以accept it as the answer。【参考方案2】:encoding
生成的所有染色体都是相同的,因此尽管parent_selection
选择不同的染色体,但输出始终相同。
基于我不太熟悉的命名约定,您可能想使用这个修改后的编码函数,它会产生不同的染色体:
def encoding_diff(jobs, P_ilj):
chromosomes = []
for n in range(n_chromosomes):
i = 1
chromosome = []
while i < 4:
for j in jobs: # Initial solution: Each stage is linked to a machine available in that stage.
if i == 1:
l = 1
elif i == 2:
l = 3
else:
l = 5
# [job,stage,Order_ID,duration,machine_ID]
gene = [j, i, np.random.rand(), P_ilj[i][l][j], l]
chromosome.append(gene)
i += 1
chromosomes.append(chromosome)
return chromosomes
【讨论】:
对不起,如果我不清楚。起始溶液/染色体(=初始种群)确实是相同的(除了订单ID(=基因[2])。但是随机选择的这些染色体(父母)的一束将通过随机突变(变化)改变到机器ID条目。起初,染色体是一样的,但变异后它们应该不再是了。parent_selection函数选择要改变的染色体,变异函数改变它们。但错误是变化不是随机的,但所有父染色体之间都是一样的。感谢您的努力 :) 简而言之:我认为编码和父选择对我来说很好。然而,突变函数为每个父染色体输入返回相同的机器变化/突变。以上是关于随机染色体突变在整个人群中是相同的的主要内容,如果未能解决你的问题,请参考以下文章