问题描述
我正在为遗传算法开发一个变异函数,但是我对numpy还是很陌生。
默认的突变方法如下:
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)]
默认的mutationprob设置为1 /染色体长度。种群每行包含不同的染色体,染色体长561,在每个位置都有0或1。
我试图做的是基于该染色体的0s和1s的频率来设置突变的概率,这样当1s很少的染色体发生突变时,将0转换为1的可能性就很高。就是相反。
目前我有这样的东西:
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)]
对于固定突变概率的情况,最后两行与当前存在的两行相同。 我的问题是上面的第3行。 mProbZero和mProbOne是一维numpy数组。我得到一个
ValueError: operands could not be broadcast together with shapes (2,5) (2,) (2,)
跟进:以下代码似乎可以工作,尽管可能比必要多了四行...有什么办法可以更好地做到这一点?
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)]
解决方法
具有(2,1)值的(2,3)条件:
In [470]: np.where(np.array([[1,1],[0,1,1]]),np.array([['a'],['b']]),np.array([['c'],['d']]))
Out[470]:
array([['a','c','a'],['d','b','b']],dtype='<U1')
具有(3,)个值(通过广播的(1,3)):
In [471]: np.where(np.array([[1,np.array(['a','c']),np.array(['d','e','f']))
Out[471]:
array([['a','c'],'c']],dtype='<U1')
在两种情况下,结果形状都与条件的形状匹配。
,我相信您正在使用二进制遗传算法。这意味着在您的突变中,您需要将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