python - How do I do something like numpy where(2darray ==0, 1darray, 1darray)
问题描述
I'm working on a mutation function for a genetic algorithm, but I'm pretty new to numpy.
The default mutation method looks like this:
whereMutate = np.random.rand(np.shape(population)[0],np.shape(population)[1])
population[np.where(whereMutate < self.mutationProb)] = 1 - population[np.where(whereMutate < self.mutationProb)]
The default mutationprob is set to 1/chromosome length. Population contains a different chromosome on each row and chromosomes are 561 long, with a 0 or 1 at each position.
What I was trying to do is to set the probability of mutation based upon the frequency of 0s and 1s for that chromosome, so that when a chromosome with very few 1s mutates it is just as likely to switch a 0 to a 1 as it is to go the other way.
Currently I have something like this:
mProbOne = 0.5/np.count_nonzero(population, axis=1)
mProbZero = 0.5/np.count_nonzero(population == 0, axis=1)
probs = np.where(population == 0, mProbZero, mProbOne)
# Something like the above ought to give me a 2d array
# with probability of mutation for each position in the chromosome,
# separately for each chromosome
whereMutate = np.random.rand(np.shape(population)[0],np.shape(population)[1]
population[np.where(whereMutate < probs)] = 1-population[np.where(whereMutate < self.mutationProb)]
The last two lines are just the same as the currently existing two lines for the case where mutation probability is fixed. My issue is line 3 above. mProbZero and mProbOne are 1d numpy arrays. I am getting a
ValueError: operands could not be broadcast together with shapes (2,5) (2,) (2,)
Follow-up: the following code seems to work, though it's probably about 4 lines more than necessary... is there any way to do this better?
mProbZero = 0.5/np.count_nonzero(population == 0, axis=1)
mProbOne = 0.5/np.count_nonzero(population, axis=1)
probs = np.zeros(np.shape(population))
probs[np.where(population == 0)] = mProbZero[np.where(population == 0)[0]]
probs[np.where(population == 1)] = mProbOne[np.where(population == 1)[0]]
whereMutate = np.random.rand(np.shape(population)[0],np.shape(population)[1])
population[np.where(whereMutate < self.mutationProb)] = 1 - population[np.where(whereMutate < self.mutationProb)]
解决方案
我相信您正在使用二进制遗传算法。这意味着在您的突变中,您需要将 1 转换为 0 并将 0 转换为 1。我不知道您的人口是什么样的。对于一个简单的方法,您可以修改此代码。这里我使用选择随机位置,您可以更改为突变概率。
def binary_mutation(parent1):
posi = random.randint(0, len(parent1)-1)
if parent1[posi] == 1:
parent1[posi] = 0
elif parent1[posi] == 0:
parent1[posi] = 1
return parent1
推荐阅读
- php - 如何将 Windows 的运行时库可移植地包含到二进制 PHP CLI
- terraform - 使用 terraform 添加 azure SQL 用户
- ios - 如何创建混合开发 pod
- java - 有没有办法将 jpa 谓词数组传递给 KOTLIN 中的标准构建器?
- javascript - 如何在 JavaScript 文件中使用 jquery
- vba - 从 Access 导出图标图像的最佳方法?
- microcontroller - 数据采集
- python - 如何将横向excel数据更改为表格格式
- php - 在 PHP 中将批量数据库插入到多个表中(具有相互关联)
- angular - Angular 环境循环依赖