C#实现遗传算法,模拟花朵的进化。

 以下代码实现了一个简单的花朵进化的模拟过程。
花朵的种群数量是10,共进化了50代。

通过运行程序,你会发现通过不断的进化,种群的总的适应环境的能力在逐步提高(fitness的值下降)。

实现代码:

using System;
using System.Collections.Generic;
using System.Text;

namespace GA
{
    
class Program
    
{
        
static void Main(string[] args)
        
{
            World world 
= new World();

            world.Init();

            
for (int i = 0; i < 50; i++)
            
{
                world.Evolve();

                Console.WriteLine(i);
                world.Show();
            }

        }

    }


    
class World
    
{
        
int kMaxFlowers = 11;

        Random Rnd 
= new Random();

        
public int[] temperature;

        
public int[] water;

        
public int[] sunlight;

        
public int[] nutrient;

        
public int[] beneficialInsect;

        
public int[] harmfulInsect;

        
public int currentTemperature;

        
public int currentWater;

        
public int currentSunlight;

        
public int currentNutrient;

        
public int currentBeneficialInsect;

        
public int currentHarmfulInsect;

        
public World()
        
{
            temperature 
= new int[kMaxFlowers];
            water 
= new int[kMaxFlowers];
            sunlight 
= new int[kMaxFlowers];
            nutrient 
= new int[kMaxFlowers];
            beneficialInsect 
= new int[kMaxFlowers];
            harmfulInsect 
= new int[kMaxFlowers];
        }


        
/// <summary>
        
/// 初始化第一代花朵的基因结构
        
/// </summary>

        public void Init()
        
{

            
for (int i = 1; i < kMaxFlowers; i++)
            
{
                temperature[i] 
= Rnd.Next(175);

                water[i] 
= Rnd.Next(175);

                sunlight[i] 
= Rnd.Next(175);

                nutrient[i] 
= Rnd.Next(175);

                beneficialInsect[i] 
= Rnd.Next(175);

                harmfulInsect[i] 
= Rnd.Next(175);
            }


            currentTemperature 
= Rnd.Next(175);

            currentWater 
= Rnd.Next(175);

            currentSunlight 
= Rnd.Next(175);

            currentNutrient 
= Rnd.Next(175);

            currentBeneficialInsect 
= Rnd.Next(175);

            currentHarmfulInsect 
= Rnd.Next(175);

        }


        
/// <summary>
        
/// 越大说明花朵的适应环境的能力差,小说明适应环境的能力强
        
/// </summary>
        
/// <param name="flower"></param>
        
/// <returns></returns>

        private int Fitness(int flower)
        
{
            
int theFitness = 0;

            theFitness 
= Math.Abs(temperature[flower] - currentTemperature);

            theFitness 
= theFitness + Math.Abs(water[flower] - currentWater);

            theFitness 
= theFitness + Math.Abs(sunlight[flower] -

                                                  currentSunlight);

            theFitness 
= theFitness + Math.Abs(nutrient[flower] -

                                                  currentNutrient);

            theFitness 
= theFitness + Math.Abs(beneficialInsect[flower] -

                                                  currentBeneficialInsect);

            theFitness 
= theFitness + Math.Abs(harmfulInsect[flower] -

                                                  currentHarmfulInsect);

            
return (theFitness);
        }


        
/// <summary>
        
/// 排除适应能力差的花朵,让适应能力强的花朵杂交繁殖,产生下一代。同时有一定的概率变异。
        
/// </summary>

        public void Evolve()
        
{
            
int[] fitTemperature = new int[kMaxFlowers];

            
int[] fitWater = new int[kMaxFlowers];

            
int[] fitSunlight = new int[kMaxFlowers];

            
int[] fitNutrient = new int[kMaxFlowers];

            
int[] fitBeneficialInsect = new int[kMaxFlowers];

            
int[] fitHarmfulInsect = new int[kMaxFlowers];

            
int[] fitness = new int[kMaxFlowers];

            
int i;

            
int leastFit = 0;

            
int leastFitIndex = 1;

            
for (i = 1; i < kMaxFlowers; i++)

                
if (Fitness(i) > leastFit)
                
{

                    leastFit 
= Fitness(i);

                    leastFitIndex 
= i;

                }


            temperature[leastFitIndex] 
= temperature[Rnd.Next(110)];

            water[leastFitIndex] 
= water[Rnd.Next(110)];

            sunlight[leastFitIndex] 
= sunlight[Rnd.Next(110)];

            nutrient[leastFitIndex] 
= nutrient[Rnd.Next(110)];

            beneficialInsect[leastFitIndex] 
= beneficialInsect[Rnd.Next(110)];

            harmfulInsect[leastFitIndex] 
= harmfulInsect[Rnd.Next(110)];

            
for (i = 1; i < kMaxFlowers; i++)
            
{

                fitTemperature[i] 
= temperature[Rnd.Next(110)];

                fitWater[i] 
= water[Rnd.Next(110)];

                fitSunlight[i] 
= sunlight[Rnd.Next(110)];

                fitNutrient[i] 
= nutrient[Rnd.Next(110)];

                fitBeneficialInsect[i] 
= beneficialInsect[Rnd.Next(110)];

                fitHarmfulInsect[i] 
= harmfulInsect[Rnd.Next(110)];

            }


            
for (i = 1; i < kMaxFlowers; i++)
            
{

                temperature[i] 
= fitTemperature[i];

                water[i] 
= fitWater[i];

                sunlight[i] 
= fitSunlight[i];

                nutrient[i] 
= fitNutrient[i];

                beneficialInsect[i] 
= fitBeneficialInsect[i];

                harmfulInsect[i] 
= fitHarmfulInsect[i];

            }


            
for (i = 1; i < kMaxFlowers; i++)
            
{

                
if (Rnd.Next(1100== 1)

                    temperature[i] 
= Rnd.Next(175);

                
if (Rnd.Next(1100== 1)

                    water[i] 
= Rnd.Next(175);

                
if (Rnd.Next(1100== 1)

                    sunlight[i] 
= Rnd.Next(175);

                
if (Rnd.Next(1100== 1)

                    nutrient[i] 
= Rnd.Next(175);

                
if (Rnd.Next(1100== 1)

                    beneficialInsect[i] 
= Rnd.Next(175);

                
if (Rnd.Next(1100== 1)

                    harmfulInsect[i] 
= Rnd.Next(175);

            }


        }


        
/// <summary>
        
/// 显示种群中个体对环境的适应能力,还有所有个体对环境的适应能力之和。
        
/// </summary>

        public void Show()
        
{
            
int sum = 0;
            
for (int i = 1; i < kMaxFlowers; i++)
            
{
                
int fitness = Fitness(i);
                sum 
+= fitness;
                Console.WriteLine(
"No." + i + "'s fitness is " + fitness);
            }


            Console.WriteLine(
"fitness sum is " + sum);
        }

    }

}

posted @ 2008-01-09 14:39 逖靖寒 阅读(2772) 评论(24)  编辑 收藏 所属分类: 读书算法

  回复  引用  查看    
#1楼 2008-01-09 14:45 | overred      
lz不会是搞生物的吧?
当年我们还模拟细胞分裂进化呢
把他扔到一台电脑上跑1个月后看结果
  回复  引用  查看    
#2楼 [楼主]2008-01-09 14:47 | 逖靖寒      
@overred
嘿嘿,我高中的时候就生物成绩好点,可惜上了大学考试学习计算机了。
  回复  引用  查看    
#3楼 2008-01-09 15:18 | Clark Zheng      
弄个打包下载,让俺先看看效果
  回复  引用  查看    
#4楼 [楼主]2008-01-09 15:52 | 逖靖寒      
@Clark Zheng
您只需建立一个控制台程序,然后把以上代码复制过去即可。
  回复  引用  查看    
#5楼 2008-01-09 16:13 | Clark Zheng      
嗯,试了一下,说实话,看不太懂
  回复  引用  查看    
#6楼 [楼主]2008-01-09 16:18 | 逖靖寒      
@Clark Zheng
呵呵,您可以去网站查找一些有关GA算法的介绍,然后配合我的源代码来理解。
如果有时间,我会写一篇关于GA入门性介绍的文章的。
  回复  引用    
#7楼 2008-01-09 16:52 | CBChen [未注册用户]
刚才看了看了一下搂主的程序,但是有几个疑问,请搂住不吝赐教
1、很多Rnd.Next(1, 10)的地方为什么不能用Rnd.Next(1, kMaxFlowers)
2、在Evolve函数里面只看到了选择和变异,但是没有看到杂交过程?
3、在选择函数中,搂主使用了随机选择,但是如果使选择的概率略倾向于更优的染色体,那么是不是可以加快收敛速度?
  回复  引用    
#8楼 2008-01-09 16:54 | CBChen [未注册用户]
不好意思,刚才看错了
是有杂交函数,但是好像是全面杂交,每次杂交个体都是1到kMaxFlowers,马并且是全部基因位都进行杂交,这样的话每一代都想当于重新产生的吧?这样做会不会有问题?
  回复  引用  查看    
#9楼 2008-01-09 17:26 | Icebird      
遗传算法 - 百度百科
http://baike.baidu.com/view/45853.htm
  回复  引用  查看    
#10楼 [楼主]2008-01-09 17:52 | 逖靖寒      
@CBChen
--引用--------------------------------------------------
CBChen: 刚才看了看了一下搂主的程序,但是有几个疑问,请搂住不吝赐教
1、很多Rnd.Next(1, 10)的地方为什么不能用Rnd.Next(1, kMaxFlowers)
2、在Evolve函数里面只看到了选择和变异,但是没有看到杂交过程?
3、在选择函数中,搂主使用了随机选择,但是如果使选择的概率略倾向于更优的染色体,那么是不是可以加快收敛速度?
--------------------------------------------------------
1 是,是应该用Rnd.Next(1, kMaxFlowers),这样可以方便修改种群的个数。
2 有杂交过程
for (i = 1; i < kMaxFlowers; i++)
{

fitTemperature[i] = temperature[Rnd.Next(1, 10)];

fitWater[i] = water[Rnd.Next(1, 10)];

fitSunlight[i] = sunlight[Rnd.Next(1, 10)];

fitNutrient[i] = nutrient[Rnd.Next(1, 10)];

fitBeneficialInsect[i] = beneficialInsect[Rnd.Next(1, 10)];

fitHarmfulInsect[i] = harmfulInsect[Rnd.Next(1, 10)];

}

for (i = 1; i < kMaxFlowers; i++)
{

temperature[i] = fitTemperature[i];

water[i] = fitWater[i];

sunlight[i] = fitSunlight[i];

nutrient[i] = fitNutrient[i];

beneficialInsect[i] = fitBeneficialInsect[i];

harmfulInsect[i] = fitHarmfulInsect[i];

}
3 可以
  回复  引用  查看    
#11楼 [楼主]2008-01-09 17:54 | 逖靖寒      
@CBChen
不是重新产生,而是利用已有的染色体杂交新的后代。
  回复  引用  查看    
#12楼 [楼主]2008-01-09 17:54 | 逖靖寒      
@Icebird
呵呵,Baidu的介绍一般都不准确,只适合大概的了解。
  回复  引用  查看    
#13楼 2008-01-09 22:58 | jillzhang      
遗传算法和蚁群算法这些都属于人工智能的范围,对没有数学基础的学习者而言,比较难入门
  回复  引用  查看    
#14楼 [楼主]2008-01-10 08:18 | 逖靖寒      
@jillzhang
呵呵,遗传算法和蚁群算法这些都属于人工智能的范围。
我对蚁群算法不了解,但是如果单单想入门遗传算法,有初中的数学基础和生物基础就足够了。
  回复  引用    
#15楼 2008-01-10 13:30 | Higood [未注册用户]
淘汰fitness最小的?

int leastFit = 0;

int leastFitIndex = 1;

for (i = 1; i < kMaxFlowers; i++)

if (Fitness(i) > leastFit)
{

leastFit = Fitness(i);

leastFitIndex = i;

}
  回复  引用    
#16楼 2008-01-10 13:38 | Higood [未注册用户]
OK,明白了
  回复  引用  查看    
#17楼 [楼主]2008-01-10 13:58 | 逖靖寒      
@Higood
hehe.
  回复  引用    
#18楼 2008-01-10 18:14 | wyn [未注册用户]
不给思路,直接上代码有啥意义吗?你是讲算法还是秀代码呀?
  回复  引用  查看    
#19楼 [楼主]2008-01-10 18:49 | 逖靖寒      
@wyn
代码就是思路、呵呵。
  回复  引用    
#20楼 2008-01-10 23:59 | ajmu [未注册用户]
思路不错
  回复  引用  查看    
#21楼 [楼主]2008-01-11 08:13 | 逖靖寒      
@ajmu
谢谢。
  回复  引用    
#22楼 2008-01-11 11:16 | A.Z! [未注册用户]
期待你的下一篇。
  回复  引用    
#23楼 2008-01-16 21:03 | hexu'lp [未注册用户]
看起来很好玩哦
  回复  引用  查看    
#24楼 2008-02-06 05:00 | Atrhis      
有意思
虽然不懂这是干什么用的

标题  
姓名  
主页