遗传算法
示例为计算函数为y = -x*x+ 1024的最大值,-32<=x<=31.
参考: http://blog.csdn.net/ljp1919/article/details/42425281
采用轮盘赌算法作为选择算子的算法
核心算法
轮盘赌
/// <summary>
/// 更新下一代;
/// 基于轮盘选择选择方法,进行基因型的选择;
/// </summary>
private static void UpdateNext()
{
// 获取总的fit;
double totalFitValue = 0;
for (int i = 0; i < chromosomes.Count; i++)
{
//适应度为负数的取0;
if (chromosomes[i].fitValue <= 0)
{
totalFitValue += 0;
}
else
{
totalFitValue += chromosomes[i].fitValue;
}
}
Console.WriteLine("totalFitValue " + totalFitValue);
//算出每个的fit percent;
for (int i = 0; i < chromosomes.Count; i++)
{
if (chromosomes[i].fitValue <= 0)
{
chromosomes[i].fitValuePercent = 0;
}
else
{
chromosomes[i].fitValuePercent = chromosomes[i].fitValue / totalFitValue;
}
Console.WriteLine("fitValuePercent " + i + " " + chromosomes[i].fitValuePercent);
}
计算累积概率;
第一个的累计概率就是自己的概率;
chromosomes[0].probability = chromosomes[0].fitValuePercent;
Console.WriteLine("probability 0 " + chromosomes[0].probability);
double probability = chromosomes[0].probability;
for (int i = 1; i < chromosomes.Count; i++)
{
if (chromosomes[i].fitValuePercent != 0)
{
chromosomes[i].probability = chromosomes[i].fitValuePercent + probability;
probability = chromosomes[i].probability;
}
Console.WriteLine("probability " + i + " " + chromosomes[i].probability);
}
chromosomesChild.Clear();
//轮盘选择选择方法,用于选出前两个;
for (int i = 0; i < chromosomes.Count; i++)
{
//产生0-1之前的随机数;
//int seed = i * 100 / 3;
double rand = random.NextDouble();//0.0-1.0
Console.WriteLine("挑选的rand " + rand);
if (rand < chromosomes[0].probability)
{
chromosomesChild.Add(chromosomes[0].Clone());
}
else
{
for (int j = 0; j < chromosomes.Count - 1; j++)
{
if (chromosomes[j].probability <= rand && rand <= chromosomes[j + 1].probability)
{
chromosomesChild.Add(chromosomes[j + 1].Clone());
}
}
}
}
for (int i = 0; i < chromosomes.Count; i++)
{
chromosomes[i] = chromosomesChild[i];
}
}
交叉操作
/// <summary>
/// 交叉操作;
/// </summary>
private static void CrossOperate()
{
/** bit[0]~bit[5] fit
* 4 000 110 12
* 3 001 010 9
* child1 000 010 14
* child2 001 110 5
*/
int rand1 = random.Next(0, 6);//0-5;
int rand2 = random.Next(0, 6);//0-5;
if (rand1 > rand2)
{
var t = rand1;
rand1 = rand2;
rand2 = t;
}
Console.WriteLine("交叉的rand " + rand1 + " - " + rand2);
for (int j = 0; j < chromosomes.Count; j = j + 2)
{
for (int i = rand1; i <= rand2; i++)
{
//将第0个给第2个;
var t = chromosomes[j].bits[i];
chromosomes[j].bits[i] = chromosomes[j + 1].bits[i];//第一条和第三条交叉;
chromosomes[j + 1].bits[i] = t;
}
chromosomes[j].fitValue = GetFitValue(DeCode(chromosomes[j].bits));
chromosomes[j + 1].fitValue = GetFitValue(DeCode(chromosomes[j + 1].bits));
}
}
变异操作
/// <summary>
/// 变异操作;
/// </summary>
private static void VariationOperate()
{
int rand = random.Next(0, 50);
Console.WriteLine("变异的rand " + rand);
if (rand < 5)//5/50 = 0.1的概率进行变异;rand<5;
{
Console.WriteLine("开始变异");
int col = random.Next(0, 6);
int row = random.Next(0, 4);
Console.WriteLine("变异的位置 " + row + " " + col);
// 0变为1,1变为0;
if (chromosomes[row].bits[col] == 0)
{
chromosomes[row].bits[col] = 1;
}
else
{
chromosomes[row].bits[col] = 0;
}
chromosomes[row].fitValue = GetFitValue(DeCode(chromosomes[row].bits));
}
}
源码: https://github.com/onelei/Algorithm/tree/master/GeneticAlgorithm