python - 快速进化算法突变:突变 n 个随机基因而不是评估每个基因
问题描述
我正在尝试优化我的遗传算法的代码。DNA 目前是一个字典,用于提高适应度计算的查找速度,但可以轻松更改为 numpy 数组。
突变率应该是 1/L,L 是 DNA 的长度。
此解决方案有效,但速度很慢:
# Iterate through genome, flip a gene with a probability of 1/L
def mutate(self):
self.dna = dict(
[(i, flip(self.dna[i])) if random.randint(0,num_genes) < 1
else (i, self.dna[i]) for i in range(num_genes)]
)
这个解决方案的速度大约是原来的两倍,但由于某种原因,它会产生更糟糕的结果:
# Select n number of genes calculated by 1/L, then change n random genes
def mutate(self):
num_mutations = sum(np.random.choice([0,1], num_genes, p=[(num_genes-1)/num_genes, 1/num_genes]))
for i in np.random.choice(num_genes-1, num_mutations):
self.dna[i] = flip(self.dna[i])
据我所知,它们突变了相同数量的基因,并且输出应该是相同的。使用设置的随机种子运行 10 次表明后一种方法会导致更差的适应度结果。
为什么第二种方法会导致更差的 dna 适应性?这些方法的结果有何不同?
感谢您的任何帮助。
解决方案
首先:矢量化
当您的索引是整数时,使用 dict 是没有意义的 - 查找整数索引总是比使用哈希表快。您也可以使用 numpy 对其进行矢量化 - 使您self.dna
的 numpy 数组而不是列表或字典,这可能会提高 10x-100x 的速度。
def flip(x): # x is a vector of genes, lets a binary array here
return ~x
mutation_mask = np.random.rand(n_genes)<1./len(self.dna)
self.dna[mutation_mask] = flip(dna[mutation_mask])
其次:为什么你的两种算法不同:
我不知道,它们看起来应该在统计上是相同的。我能想到的一件事是,在第二种情况下,您正在使用 进行修改self.dna
,self.dna[i]=...
而不是重新分配self.dna=...
,因此在第二种情况下,代码中任何其他具有旧的区域self.dna
的副本也会发生更改。self.dna = self.dna.copy()
您可以通过在第二个示例中的 for 循环之前插入来解决此问题。
推荐阅读
- javascript - Json 从 Javascript 解码到 php 到 Javascript
- python - 调用 pandas 分析后,Matplotlib pyplot 图看起来不同。我怎样才能解决这个问题?
- python - 我无法导入 CSV 文件?
- visual-studio - 如何在 Visual Studio 2017 的 x86 程序集中使用 printf?
- php - 数据未插入表
- java - java.lang.ClassNotFoundException: com.google.wireless.android.sdk.stats.IntellijIndexingStats$Index
- c# - 使用 .NET 将 .ai 转换为另一种矢量图形格式(如 .eps 或 .svg)
- node.js - 我们在 nodejs 程序的标头中发送的参数的数据类型是什么?
- java - 如何使用 OpenJDK 配置 JAVA HOME?
- spring-boot - Spring Security 的默认登录表单可以与 JWT 一起使用吗?