有一个C#遗传算法程序求y=x*x在[0,31]范围内的极值。有的地方看不太懂,请大神解读,最好详细一点。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//遗传算法求Y=X*X 在区间[0-31]的最大值
namespace 遗传算法
{
class Program
{
//定义样本数
static int N = 10;
//定义DNA位数
static int M = 5;
//定义样本DNA数组
static int[,] DNA = new int[N,M];//定义多维数组
//定义样本表现值
static int[] show = new int[N];
//定义样本存活累计概率0-1
static double[] alive = new double[N];
//定义淘汰阈值
static int sigma = 3;
//定义繁衍代数
static int T = 100;
//定义交换基因次数
static int C = 1;
//将样本10进制求2进制 j表示位数
static void tentotwo()
{
for (int i = 0; i < N;i++ )
{
int j = 0;
int tempshow = show[i];
while (tempshow != 0)
{
DNA[i,j] = tempshow% 2;
tempshow /= 2;
j++;
}
}
}
//将样本2进制转10进制
static void twototen()
{
for (int i = 0; i < N; i++)
{
int sum = 0;
for(int j=0;j<M;j++)
{
sum += DNA[i,j]*(int)System.Math.Pow(2,j);
}
show[i] = sum;
}
}
//适应度函数
static int f(int x)
{
int result = -x * x + 31*x;
return (result);
}
//求累计存活概率函数
static void icanlive()
{
int sum = 0;
double alivesum = 0;
for (int i = 0; i < N; i++)
{
sum += f(show[i]);
}
for (int i = 0; i < N; i++)
{
alivesum += (double)f(show[i]) / (double)sum; //?
alive[i] = alivesum;
}
}
//淘汰函数
static void dieout()
{
int[] times = new int[N];
for (int i = 0; i < times.Length;i++ )
{
times[i] = 0;
}
Random ro = new Random(GetRandomSeed());
//遗传过程
for (int i = 0; i < 2*N; i++)//?
{
double myro = (double)ro.Next(0, 100) / 100;
for (int j = 0; j < N; j++)
{
if (myro<alive[j])
{
if (j != 0 && myro > alive[j - 1])
{
times[j] += 1;
break;
}
else if(j==0)
{
times[j] += 1;
break;
}
}
}
}
//找出本次遗传中最强势种族//?
int max = times[0];
int sign = 0;
for (int y = 0; y < N; y++)
{
if (times[y] > max)
{
max = times[y];
sign = y;
}
}
for (int y = 0; y < N; y++)
{
//小于阈值的样本被淘汰,改样本被适应度最强的样本取代
if (times[y] < sigma)//?
{
show[y] = show[sign];
}
}
}
//基因交换函数:随机选出2队样本随机交换2位DNA
static void exchangeDNA()
{
Random ro = new Random(GetRandomSeed());
int a;
int b;
int x1;
int x2;
int y1;
int y2;
int iUp1 = M, iUp2 = N;
int iDown = 0;
int temp;
for (int i = 0; i < C; i++)
{
x1 = ro.Next(iDown, iUp1);
x2 = ro.Next(iDown, iUp1);
y1 = ro.Next(iDown, iUp1);
y2 = ro.Next(iDown, iUp1);
a = ro.Next(iDown, iUp2);
b = ro.Next(iDown, iUp2);
temp = DNA[a, x1];
DNA[a, x1] = DNA[b, y1];
DNA[b, y1] = temp;
temp = DNA[a, x2];
DNA[a, x2] = DNA[b, y2];
DNA[b, y2] = temp;
}
}
static void Main(string[] args)
{
//初始化样本值
show[0] = 1;
show[1] = 2;
show[2] = 23;
show[3] = 12;
show[4] = 4;
show[5] = 7;
show[6] = 9;
show[7] = 20;
show[8] = 29;
show[9] = 10;
tentotwo();
Console.Write("\n父代样本\n");
Console.Write("样本表现值:");
for (int j = 0; j < N; j++)
{
Console.Write(show[j].ToString() + " ");
}
Console.Write("\n样本适应度:");
for (int j = 0; j < N; j++)
{
Console.Write(f(show[j]).ToString() + " ");
}
for (int i = 0; i < T;i++ )
{
//交换DNA
exchangeDNA();
//DNA触发变现值
twototen();
//表现值求出存活概率
icanlive();
//根据存活概率淘汰低者
dieout();
//表现值触发DNA
tentotwo();
Console.Write("\n\n第" + (i + 1) + "代样本\n");
Console.Write("样本表现值:");
for (int j = 0; j < N; j++)
{
Console.Write(show[j].ToString() + " ");
}
Console.Write("\n样本适应度:");
for (int j = 0; j < N; j++)
{
Console.Write(f(show[j]).ToString() + " ");
}
}
Console.Write("\n\n程序运行完毕\n");
Console.ReadKey();
}
//产生随机数种子
static int GetRandomSeed()
{
byte[] bytes = new byte[4];
System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
rng.GetBytes(bytes);
return BitConverter.ToInt32(bytes, 0);
}
}
}
问题如下:1.淘汰阈值是个什么概念,为什么要定义成3?
2.淘汰函数中 time[]表示什么概念?
3.遗传过程中 for (int i = 0; i < 2*N; i++)为什么要循环2N次?
[解决办法]
阈值就是个范围界限,一个值与其比较,来决定是否舍弃
time[]是局部变量,用来存放计算结果
具体涉及到算法的可以参考http://baike.baidu.com/link?url=JCmENpRkHvIJWDXfUyZ4z1m9zXdqzAHQNajkF4oEQRwF8FAJKvUBz6MjY87tdh-6