神经网络数据结构

1. 遗传算法的数据结构

大致画了下数据结构的逻辑图,如下:




















参加生存竞争的整个群体称为种群(Population),种群中所有参与进化的个体(Chromosome)的数量一般为一个定值,而每个个体可能含有多于一个基因(Gene)。

例如,求解一个Camel函数在区间-100<x,y<100上边的最小值:
f(x,y)=[4 - 2.1(x^2) + (x^3)/3](x^2) + xy +[-4 +4(y^2)](y^2)
这时候就需要两个基因,每个基因上限是100,下限是-100. 

假设数值求解的精度为10^(-7),那么对应的二进制编码长度N可以这样确定
(2^N)-1 >= [ 100 - ( -100 ) ] / [ 10^(-7) ]
于是,将一个十进制数字x转化为二进制
x' = [x- (-100)] * [(2^N) -1] / [ 100 - ( -100 ) ]
同样,也可以将一个二进制数字x'转化为十进制数字x

程序中,数据结构可以这样定义
 1  struct  Gene
 2  {
 3       long   double  Upper;                       // upper boundary of the value
 4       long   double  Lower;                       // lower boundary of the value
 5       long   double  Value;                       // decimal value of the gene
 6      std :: vector <   int   >  Binary_Array;       // binary form of the value
 7       long   double  Accuracy;                    // accuracy of the value
 8  };
 9 
10  struct  Chromosome
11  {
12      std :: vector <  Gene  >  Gene_Array;    // Gene[]
13       long   double  Fitness;                 // the weigh of the chromosome in ga
14  };
15 
16  struct  Population
17  {
18      std :: vector <  Chromosome  >  Chromosome_Array;    // Chromosome[]
19      
20       long   double  Mutation_Probability;                // probability of mutation
21       long   double  Crossover_Probability;               // probability of crossover
22  };

2. 与数据结构相关的基本算法


1) 基因的自动初始化 --在搜索区间中随机生成初始基因
     
 1  // generate random value
 2  void  initialize( Gene &  g)
 3  {
 4       const   long   double  Ran  =  ran();
 5       const   long   double  Upper  =  g.Upper;
 6       const   long   double  Lower  =  g.Lower;
 7       // const long double Accuracy = g.Accuracy;
 8      assert( Upper  >  Lower );
 9 
10      g.Value  =  Lower  +  Ran  *  ( Upper  -  Lower );
11  }
12 

2) 基因的二进制编码--将十进制数据编码为二进制
 1  // decimal value -> binary form
 2  void  encoding( Gene &  g )
 3  {
 4       const   long   double  Value  =  g.Value;
 5       const   long   double  Upper  =  g.Upper;
 6       const   long   double  Lower  =  g.Lower;
 7       const   long   double  Accuracy  =  g.Accuracy;
 8 
 9      unsigned  int  Size  =   1                         +
10      static_cast <  unsigned  int   >
11      (
12          log( ( Upper  -  Lower )  /  ( Accuracy ) )  /
13          log(  2.0  )
14      );
15 
16       if  ( Size  >   63  )
17          Size  =   63 ;
18 
19       const  unsigned  long   long  Max  =   1   <<  Size;
20 
21      unsigned  long   long  x  =
22      static_cast <  unsigned  long   long   >
23      (
24          static_cast <   long   double > ( Max  - 1  )      *
25          ( Value  -  Lower )                        /
26          ( Upper  -  Lower )
27      );
28 
29      std :: vector < int >  Binary_Array;
30 
31       for  ( unsigned  int  i  =   0 ; i  <=  Size;  ++ i )
32      {
33           if  ( x  &   1  )     // case odd
34          {
35              Binary_Array.push_back(  1  );
36          }
37           else              // case even
38          {
39              Binary_Array.push_back(  0  );
40          }
41          x  >>=   1 ;
42      }
43 
44      g.Binary_Array  =  Binary_Array;
45 
46  }
47 

3)二进制向十进制的解码--将二进制数据解码为十进制
 1  // binary form -> decimal value
 2  void  decoding( Gene &  g )
 3  {
 4       const  unsigned  int  Size  =  g.Binary_Array.size();
 5      assert( Size  >   0  );
 6 
 7       const   long   double  Upper  =  g.Upper;
 8       const   long   double  Lower  =  g.Lower;
 9       // const long double Accuracy = g.Accuracy;
10       const  std::vector < int >  Binary_Array  =  g.Binary_Array;
11 
12       const  unsigned  long   long  Max  =   1   <<  Size;
13      unsigned  long   long  x  =   0 ;
14 
15       for ( unsigned  int  i  =  Size; i  >   0 -- i )
16      {
17          x  +=  Binary_Array[i - 1 ];
18          x  <<=   1 ;
19      }
20       // x += Binary_Array[0];
21 
22       const   long   double  Value  =  Lower          +
23          static_cast < long   double > ( x )        /
24          static_cast < long   double > ( Max  -   1  )  *
25          ( Upper  -  Lower );
26 
27      g.Value  =  Value;
28  }

4)普通二进制编码转到格雷码
多说一点,在进行二进制交叉的时候,使用格雷码比普通的二进制编码要有效一点。
例如,如果采用普通二进制编码,8可以表示为1000,而7则表示为0111,四个位都是不同的,7与8仅仅相差了1,但是普通二进制编码却相差了这么多,如果对他们进行交叉的话,出来的结果偏离7与8实在太远了,而使用格雷码则可以避免这种尴尬。
这里(http://baike.baidu.com/view/358724.htm)是百度一个有关格雷码的介绍,我就不复制了,有兴趣的话过去看看。

 1  // Normal Binary Form --> Gray Binary Form
 2  void  normal2gray( Gene &  g )
 3  {
 4       const  unsigned  int  Size  =  g.Binary_Array.size();
 5      assert( Size  >   0  );
 6 
 7      std :: vector < int >  G_Binary_Array;       // gray code
 8       const  std :: vector < int >  Binary_Array  =  g.Binary_Array;
 9 
10      G_Binary_Array.push_back( Binary_Array[ 0 ] );
11       for  ( unsigned  int  i  =   1 ; i  <  Size;  ++ i )
12      {
13          G_Binary_Array.push_back( ( Binary_Array[i - 1 +  Binary_Array[i] )  &   1  );
14      }
15      g.Binary_Array  =  G_Binary_Array;
16  }
17 

5) 格雷码转换到普通二进制编码
 1  // Gray Binary Form --> Normal Binary Form
 2  void  normal2binary( Gene &  g )
 3  {
 4       const  unsigned  int  Size  =  g.Binary_Array.size();
 5      assert( Size  >   0  );
 6 
 7      std :: vector < int >  N_Binary_Array;   // Normal Binary Form
 8       const  std :: vector < int >  Binary_Array  =  g.Binary_Array;
 9 
10      unsigned  int  result  =   0 ;
11       for  ( unsigned  int  i  =   0 ; i  <  Size;  ++ i )
12      {
13          result  +=  Binary_Array[i];
14          N_Binary_Array.push_back( result  &   1  );
15      }
16 
17      g.Binary_Array  =  N_Binary_Array;
18  }
19 
20 

6) 进化种群初始化函数一 -- 生成进化个体
 1  void  initialize(    Population &  population,
 2                       const  unsigned  int  size 
 3                  )
 4  {
 5      Chromosome *  chromosome  =   new  Chromosome;
 6 
 7      population.Generation  =   1 ;
 8 
 9       for  ( unsigned  int  i  =   0 ; i  <  size;  ++ i )
10      {
11 
12          population.Chromosome_Array.push_back(  * chromosome );
13      }
14 
15      delete chromosome;
16  }
17 

7) 进化种群初始化函数二 -- 对种群中的每个个体,初始化其基因
      如上边的Camel函数,因为里边有两个自变量需要搜索,那么需要调用这个函数两次,分别对应于x和y
       append_gene( p, 100, -100, 1E-7);
       append_gene( p, 100, -100, 1E-7);
 1  void  append_gene(   Population &  population,
 2                       const   long   double &  upper,
 3                       const   long   double &  lower,
 4                       const   long   double &  accuracy
 5                  )
 6  {
 7      assert( upper  >  lower );
 8      assert( accuracy  >   0  );
 9 
10      Gene *  gene  =   new  Gene;
11 
12      gene  ->  Upper  =  upper;
13      gene  ->  Lower  =  lower;
14      gene  ->  Accuracy  =  accuracy;
15 
16       const  unsigned  int  Size  =  population.Chromosome_Array.size();
17       for  ( unsigned  int  i  =   0 ; i  <  Size;  ++ i )
18      {
19          initialize(  * gene );
20          population.Chromosome_Array[i].Gene_Array.push_back(  * gene );
21      }
22 
23      delete gene;
24  }
25 

8) 搜寻最佳适应度个体 -- 进化到指定年代后,找出最佳个体
 1  const  std :: vector <   long   double   >  elite(  const  Population &  population )
 2  {
 3       const  unsigned  int  Size  =  population.Chromosome_Array.size();
 4      assert( Size  >   0  );
 5       long   double  max  =  population.Chromosome_Array[ 0 ].Fitness;
 6      unsigned  int  index  =   0 ;
 7       for  ( unsigned  int  i  =   1 ; i  <  Size;  ++ i )
 8      {
 9           if  ( population.Chromosome_Array[i].Fitness  >  max )
10          {
11              index  =  i;
12              max  =  population.Chromosome_Array[i].Fitness;
13          }
14      }
15 
16      std :: vector < long   double >  Elite;
17       const  unsigned  int  G_Size  =  population.Chromosome_Array[ 0 ].Gene_Array.size();
18       for  ( unsigned  int  i  =   0 ; i  <  G_Size;  ++ i )
19          Elite.push_back( population.Chromosome_Array[index].Gene_Array[i].Value );
20 
21       return  Elite;
22  }

9) 随机函数
由于遗传算法是一种随机搜索算法,执行的时候需要大量的随机数(记得之前搜索四个未知数,种群100个体,进化800代,大概整个运行过程用了10^10数量级的随机数),库里的随机数生成函数肯定不行。当前使用了一个Kruth推荐的(Kruth, D. E. 1997, Seminumerical Algorithms, vol2. $3)、基于相减方法的随机数生成算法,比基于线性同余方法的快一点。
 1  #include  < ctime >
 2 
 3  static   long   double  _ran(  int &  seed );
 4 
 5  long   double  ran()
 6  {
 7       static   int  seed  =  static_cast  <  unsigned  int   > ( time( NULL ) );
 8       return  _ran( seed );
 9  }
10 
11  static   long   double  _ran(  int &  seed )
12  {
13 
14       const   int  MBIG  =   1000000000 ;
15       const   int  MSEED  =   161803398 ;
16       const   int  MZ  =   0 ;
17       const   long   double  FAC  =   1 .0E - 9L ;
18 
19       static   int  inext, inextp;
20       static   long  ma[ 56 ];
21       static   int  iff  =   0 ;
22       long  mj, mk;
23       int  i, ii, k;
24 
25       if  ( seed  <   0   ||  iff  ==   0 )
26      {
27          iff  =   1 ;
28          mj  =  MSEED  -  (seed  <   0   ?   - seed : seed);
29          mj  %=  MBIG;
30          ma[ 55 =  mj;
31          mk  =   1 ;
32           for  (i  =   1 ; i  <=   54 ; i ++ ) {
33              ii  =  ( 21   *  i)  %   55 ;
34              ma[ii]  =  mk;
35              mk  =  mj  -  mk;
36               if  (mk  <  MZ)
37                  mk  +=  MBIG;
38              mj  =  ma[ii];
39          }
40           for  (k  =   1 ; k  <=   4 ; k ++ )
41               for  (i  =   1 ; i  <=   55 ; i ++ )
42              {
43                  ma[i]  -=  ma[ 1   +  (i  +   30 %   55 ];
44                   if  (ma[i]  <  MZ)
45                      ma[i]  +=  MBIG;
46              }
47          inext  =   0 ;
48          inextp  =   31 ;
49          seed  =   1 ;
50      }
51       if  ( ++ inext  ==   56 )
52          inext  =   1 ;
53       if  ( ++ inextp  ==   56 )
54          inextp  =   1 ;
55      mj  =  ma[inext]  -  ma[inextp];
56       if  (mj  <  MZ)
57          mj  +=  MBIG;
58      ma[inext]  =  mj;
59       return  mj  *  FAC;
60  }
61 
62 
《MATLAB神经网络43个案例分析》是在《MATLAB神经网络30个案例分析》的基础上出版的,部分章节涉及了常见的优化算法(遗传算法、粒子群算法等)与神经网络的结合问题。 《MATLAB神经网络43个案例分析》可作为高等学校相关专业学生本科毕业设计、研究生课题研究的参考书籍,亦可供相关专业教师教学参考。 《MATLAB神经网络43个案例分析》共有43章目录如下: 第1章 BP神经网络的数据分类——语音特征信号分类 第2章 BP神经网络的非线性系统建模——非线性函数拟合 第3章 遗传算法优化BP神经网络——非线性函数拟合 第4章 神经网络遗传算法函数极值寻优——非线性函数极值寻优 第5章 基于BP_Adaboost的强分类器设计——公司财务预警建模 第6章 PID神经元网络解耦控制算法——多变量系统控制 第7章 RBF网络的回归--非线性函数回归的实现 第8章 GRNN网络的预测----基于广义回归神经网络的货运量预测 第9章 离散Hopfield神经网络的联想记忆——数字识别 第10章 离散Hopfield神经网络的分类——高校科研能力评价 第11章 连续Hopfield神经网络的优化——旅行商问题优化计算 第12章 初始SVM分类与回归 第13章 LIBSVM参数实例详解 第14章 基于SVM的数据分类预测——意大利葡萄酒种类识别 第15章 SVM的参数优化——如何更好的提升分类器的性能 第16章 基于SVM的回归预测分析——上证指数开盘指数预测. 第17章 基于SVM的信息粒化时序回归预测——上证指数开盘指数变化趋势和变化空间预测 第18章 基于SVM的图像分割-真彩色图像分割 第19章 基于SVM的手写字体识别 第20章 LIBSVM-FarutoUltimate工具箱及GUI版本介绍与使用 第21章 自组织竞争网络在模式分类中的应用—患者癌症发病预测 第22章 SOM神经网络的数据分类--柴油机故障诊断 第23章 Elman神经网络的数据预测----电力负荷预测模型研究 第24章 概率神经网络的分类预测--基于PNN的变压器故障诊断 第25章 基于MIV的神经网络变量筛选----基于BP神经网络的变量筛选 第26章 LVQ神经网络的分类——乳腺肿瘤诊断 第27章 LVQ神经网络的预测——人脸朝向识别 第28章 决策树分类器的应用研究——乳腺癌诊断 第29章 极限学习机在回归拟合及分类问题中的应用研究——对比实验 第30章 基于随机森林思想的组合分类器设计——乳腺癌诊断 第31章 思维进化算法优化BP神经网络——非线性函数拟合 第32章 小波神经网络的时间序列预测——短时交通流量预测 第33章 模糊神经网络的预测算法——嘉陵江水质评价 第34章 广义神经网络的聚类算法——网络入侵聚类 第35章 粒子群优化算法的寻优算法——非线性函数极值寻优 第36章 遗传算法优化计算——建模自变量降维 第37章 基于灰色神经网络的预测算法研究——订单需求预测 第38章 基于Kohonen网络的聚类算法——网络入侵聚类 第39章 神经网络GUI的实现——基于GUI的神经网络拟合、模式识别、聚类 第40章 动态神经网络时间序列预测研究——基于MATLAB的NARX实现 第41章 定制神经网络的实现——神经网络的个性化建模与仿真 第42章 并行运算与神经网络——基于CPU/GPU的并行神经网络运算 第43章 神经网络高效编程技巧——基于MATLAB R2012b新版本特性的探讨
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值