生物学中的遗传
假设将一个种群放到一个新的环境中,在环境不变的情况下,种群中适应环境的个体的基因遗传到下一代的概率就会大,不适应环境的个体的基因遗传到下一代的概率就会小,在进行N次迭代后,种群中不适应环境的基因就会逐渐消失,保留下来的都是对环境适应度高的基因。
但仅仅依靠外部的环境选择是远远不能达到我们现在的生物的多样性的,因为生物的遗传过程中还存在着基因的交叉互换和基因的变异。
遗传算法所能解决的问题
遗传算法无法确定性的给出问题的具体解,因为在遗传过程中存在着不确定因素,但能够保证在迭代次数足够多的时候,能给出问题的近似解。如果求的是最优解问题,遗传算法不一定能够得到最优解,但可以得到相对较优的解。所以,该算法适用于对解的精确度要求不高的一些问题。在概率计算中应用较广。
生物遗传图解
遗传算法图解
代码实现解决数组分割问题
一个有100个整数的数组中取10个元素,使得这10个元素的值接近于数组总值的1/10
适应度计算
//arr[][]表示选择出来的种群,这里是10和数组长度为10的二维数组
//mid 表示数组总和的1/10
//yarr 表示原来的数组
int Suff(int arr[ROW][COL],int mid,int len,int n,int *yarr,double *suf)
{
double suff = 0;
int num = 0; //子数组的和
for(int i = 0; i < n; i++)
{
num = Sum(arr[i],len,yarr); //求arr[i]数组中10个元素的和
num = abs(num-mid); //子数组和减去原数组的和的1/10
if (num == 0)
{
return i; //如果找到满足条件子数组,直接返回,不再迭代
}
suff += (double)1/num; //累加总的适应度
num = 0; //循环求解
}
*suf = suff; //将总的适应度带回
return -1; //返回总的适应度
}
Sum 求和函数
int Sum(int *arr,int len,int *yarr)
{
int sum = 0;
for(int i = 0; i < len; i++)
{
sum += yarr[arr[i]]; //arr[]中存放的是yarr总数组的下标
}
return sum;
}
选择进入下一代的个体
//选择算子设计 选出下一代个体
//index[] 记录进入下一代的个体
void Subarrs(int arr[ROW][COL],int mid,double suff
,int n,int len,int index[LEN],int *yarr)
{
double corona[LEN] = {
0};
int num = 0;
//通过轮盘赌的方法构造一个数组,将数组分段,每个段代表一个个体进入下一代的概率
//如果此处不明白,可自行查看轮盘赌构造方法
for(int i = 0; i < LEN; i++) //构造轮盘
{
num = Sum