参考的链接: 参考
算法基本思想
如上图所示的抽奖转盘,我们直观的认为“四等奖”的中奖概率最大,因为它占的面积最多,这也体现了轮盘赌算法最朴素的一个思想:被选中的概率与个体在总体中所占比例成正比。
假设我们不是用“一等奖”或“二等奖”这种定性的指标描述,而是给每个个体 [公式] 一个适应度值 [公式] ,则使用轮盘赌算法选择该个体的流程为:
计算适应度比例,即每个个体的选择概率
2.计算每个个体的累积概率,相当于转盘上的“跨度”,“跨度”越大越容易选到
即每个个体之前所有个体的选择概率之和,相当于概率论中的概率分布函数F(x)
- 随机生成
,若
,则选择个体
举个例子
若有群体pop,里面存在的个体为:
pop = ['a' ,'b', 'c', 'd', 'e']
他们的适应度(用于衡量被选择的概率)为:
obj = [1 ,3, 0, 2, 4]
判断是否选择的标准为一个随机生成的有序的序列:
ms = [0.05 , 0.2 , 0.7 , 0.8 ,0.9]
按照上述流程,计算出的相应的结果为:
- 被选择概率
p= [0.1 , 0.3, 0 , 0.2 , 0.4]
- 累积概率
q= [0.1 , 0.4 , 0.4 , 0.6 , 1.0]
即当前个体累积概率为之前所有样本的概率与自身所占概率之和。
- 选择过程
q[0] > ms [0] ---------第0个个体在此次被选择 j++
q[0] < ms [1] ---------第0个个体在此次不被选择 i++
q[1] > ms [1] ---------第1个个体在此次被选择 j++
q[1] < ms [2] ---------第1个个体在此次不被选择 i++
q[2] < ms [2] ---------第2个个体在此次不被选择 i++
q[3] < ms [2] ---------第3个个体在此次不被选择 i++
q[4] > ms [2] ---------第4个个体在此次不被选择 j++
q[4] > ms [3] ---------第4个个体在此次不被选择 j++
q[4] > ms [4] ---------第4个个体在此次不被选择 j++
最终选择的个体为第0、1、4三个个体,可见具有大概率选择那些本身适应度就比较大的个体。
写个代码
import random
def sum(fit_value):
total = 0
for i in range(len(fit_value)):
total += fit_value[i]
return total
# =============================================================================
# 累积概率计算
# =============================================================================
def cumsum(fit_value):
t = 0
for i in range(len(fit_value)):
t = t + fit_value[i]
fit_value[i] = t
return fit_value
# =============================================================================
# 轮盘赌算法
# =============================================================================
def ga_selection(pop, fit_value):
#计算累积概率
newfit_value = []#存储每个个体的累积概率
# 适应度总和
total_fit = sum(fit_value)
for i in range(len(fit_value)):
#计算每个适应度占适应度总和的比例
newfit_value.append(fit_value[i] / total_fit)
# 计算累计概率
cumsum(newfit_value)
#生成随机数序列用于选择和比较
ms = []#随机数序列
pop_len = len(pop)
for i in range(pop_len):
ms.append(random.random())
ms.sort()
#轮盘赌选择法
fitin = 0
newin = 0
newpop = pop
while newin < pop_len:
#选择--累积概率大于随机概率
if(ms[newin] < newfit_value[fitin]):
newpop[newin] = pop[fitin]
newin = newin + 1
#不选择--累积概率小于随机概率
else:
fitin = fitin + 1
pop = newpop
if __name__ == '__main__':
pop = ['a' ,'b', 'c', 'd', 'e']
obj = [1 ,3, 0, 2, 4]
#newfit_value = [0.1 , 0.4 , 0.4 , 0.6 , 1.0]
ga_selection(pop, obj)
print(pop)
轮盘赌算法也应用于遗传算法中选择和复制比较好的个体。