基于matlab的遗传算法实现50个整数选10个数——选择数的总值接近50个数总值的1/10

文章目录

题目

一个有50个整数的数组中取10个元素,是的这10个元素的值接近于数组总值的1/10。
对遗传算法不了解的同学可以先看看这篇文章——https://blog.csdn.net/BruceYeWang/article/details/116492055?spm=1001.2014.3001.5501

思路详述

1、个体选择
因为是50个数选10个数,所以本文设置10个数为一个个体,每次迭代都是在此基础之上。

2、适应度函数
设设10个数的总值为gsum,50个数总值为sum
因为题目要求选出的gsum接近于sum的1/10,所以易得适应度函数为 ∣ 1 g s u m − s u m ∗ 1 / 10 ∣ \left | \frac{1}{gsum-sum*1/10} \right | gsumsum1/101
注意,因为本文测试用例的数组总值的1/10为127.5,不是整数,所以直接用1除以差值是可以的,不会无限大,但如果你选择的数组总值的1/10为整数的话,需要对适应度函数进行一些修改,目前本人没想到什么好的方法(也没时间去想,哈哈),可以在计算适应度函数的时候修改数组总值为小数,可以加减个0.1或0.01什么的,具体数字由你自己而定,看你想要具有优良特性的个体被选中的概率有多大,越大则加减的小数越小。

3、选择
本文设定的遗传率为60%,并且每次都取出最优解直接遗传,不参与交叉和变异。选择方法为轮盘赌选择法,易操作实现。

4、编码(染色体、实数编码)
因为编码是为交叉、变异服务的,而本题其实和其他题目有所不同,就是所能取值的范围其实是写死的,不管如何交叉、变异,最终得出的数一定要在最初的50个数之中。若这50个数连在一起还好,如果是随机的数组比如[1,30,505,24,254435…],还采取二进制编码的方法很容易得出不在原数组中的数,所以为了方便操作,本文采用实数编码的方法,即设置每个数在数组中的位序作为部分DNA,每个个体即10个数的所有位序连在一起即构成了完整的染色体,每次交叉和变异操作的都是个体中的某一个数值亦或数值在原数组中的位序。

5、交叉
因为编码方法与基本的编码方法风格迥异,所以本文在交叉时互换两个个体中随机位序的数值并保证交换的数值是互相都没有的。本文设定的交叉率为30%,即每个个体会互换3个数值。

6、变异
本文原本的思路时设定一个变异率,用变异率乘以种群个数,从而得出每次迭代需要变异的个体数。这样操作是没有问题的,也很容易实现,但本文想要试试别的方法——设定一个变异率,每次迭代时,产生一个随机数,若随机数小于变异率,即随机算则一个个体的随机一个数值产生变异。第一种方法更加符合生物学,但当种群个数较少时,产生变异的概率基本为零。第二种方法在种群数量很大时,产生的变异数量很少,但在种群数量很少是,依然会产生变异。两种方法本文并未给出优劣,有待后续研究。

代码

因为csdn不支持matlab代码块&

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值