首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

有一个C#遗传算法程序求y=x*x在[0,31]范围内的极值。有的地方看不太懂,请大神解读,最好详细1点

2013-10-03 
有一个C#遗传算法程序求yx*x在[0,31]范围内的极值。有的地方看不太懂,请大神解读,最好详细一点。using Syst

有一个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

热点排行