zoukankan      html  css  js  c++  java
  • 差分进化算法(DE)的C++面向对象方法实现

    代码来源于网络,写得非常棒

      1 /*DE_test
      2  *对相应的Matlab程序进行测试
      3  */
      4 
      5 #include <iostream>
      6 #include <cmath>
      7 #include <ctime>
      8 using namespace std;
      9 
     10 //产生随机数,随机数为(0.0,1.0)
     11 double Rand_Double(void)
     12 {
     13     return static_cast<double>(rand()) / static_cast<double>(RAND_MAX);
     14 }
     15 
     16 //测试函数Hansen
     17 //参数个数为2
     18 double Hansen(double *p_pars)
     19 {
     20     return (cos(1.0) + 2.0*cos(p_pars[0] + 2.0) + 3.0*cos(2.0*p_pars[0] + 3.0)
     21         + 4.0*cos(3.0*p_pars[0] + 4.0) + 5.0*cos(4.0*p_pars[0] + 5.0))
     22         * (cos(2.0*p_pars[1] + 1.0) + 2.0*cos(3.0*p_pars[1] + 2.0) +
     23             3.0*cos(4.0*p_pars[1] + 3.0) + 4.0*cos(5.0*p_pars[1] + 4.0) + 5.0*cos(6.0*p_pars[1] + 5.0));
     24 }
     25 
     26 class CFunction
     27 {
     28 public:
     29     void *m_p_fun;//指向测试函数的指针
     30     int m_pars_num;//参数个数
     31     double m_min;//下限
     32     double m_max;//上限
     33     bool m_pos;//求解最小值还是最大值,如果是最小值则m_pos为false,如果是最大值则m_pos为true
     34 public:
     35     CFunction(void *p_fun, int pars_num, double min, double max, bool pos)
     36         :m_p_fun(p_fun), m_pars_num(pars_num), m_min(min), m_max(max), m_pos(pos)
     37     {
     38     }
     39 
     40     virtual double Compute(double *p_pars) = 0;
     41 };
     42 
     43 class CHansen :public CFunction
     44 {
     45 public:
     46     //注册函数
     47     CHansen(void)
     48         :CFunction(Hansen, 2, -10.0, 10.0, false)
     49     {
     50     }
     51 
     52     double Compute(double *p_pars)
     53     {
     54         return Hansen(p_pars);
     55     }
     56 };
     57 
     58 //个体
     59 class CIndividual
     60 {
     61 public:
     62     double *m_p_DNA;//参数
     63     double m_f;//适应值
     64     int m_DNA_length;//DNA的长度
     65 
     66 public:
     67     CIndividual(void)
     68         :m_f(0.0), m_DNA_length(0), m_p_DNA(NULL)
     69     {
     70     }
     71 
     72     ~CIndividual(void)
     73     {
     74         if (m_p_DNA != NULL)
     75             delete[] m_p_DNA;
     76     }
     77 
     78     //初始化,分配内存空间
     79     void Ini(int pars_num)
     80     {
     81         m_DNA_length = pars_num;
     82         m_p_DNA = new double[m_DNA_length];
     83     }
     84 
     85     //假定两者分配的内存空间的大小一样
     86     CIndividual& operator=(CIndividual& ind)
     87     {
     88         m_f = ind.m_f;
     89         //m_DNA_length = ind.m_DNA_length;
     90         for (int i = 0; i < m_DNA_length; ++i)
     91         {
     92             m_p_DNA[i] = ind.m_p_DNA[i];
     93         }
     94         return *this;
     95     }
     96 
     97     friend ostream& operator<<(ostream& o, CIndividual& ind)//运算符重载
     98     {
     99         return o << ind.m_f;
    100     }
    101 };
    102 
    103 
    104 int main()
    105 {
    106     //---------------------------设置随机数------------------------------------
    107     srand((unsigned int)(time(NULL)));
    108 
    109     //获得参数
    110     int Num, T;
    111     double zoom, cr;
    112 
    113     cout << "种群大小:";
    114     cin >> Num;
    115 
    116     cout << "进化代数:";
    117     cin >> T;
    118 
    119     cout << "缩放因子:";
    120     cin >> zoom;
    121 
    122     cout << "交叉因子:";
    123     cin >> cr;
    124 
    125     //----------------------对函数进行操作,注册函数------------------------------
    126     CHansen fun_Hansen;
    127 
    128     CFunction *p_fun = &fun_Hansen;//为了实现多态
    129     int pars_num = p_fun->m_pars_num;//参数个数
    130     double min = p_fun->m_min;//下限
    131     double max = p_fun->m_max;//上限
    132     bool pos = p_fun->m_pos;//求最大值还是最小值
    133 
    134     //----------------------注册种群,并分配内存空间-----------------------------
    135     CIndividual *p_old = new CIndividual[Num];
    136     CIndividual *p_new = new CIndividual[Num];
    137     for (int i = 0; i < Num; ++i)
    138     {
    139         p_old[i].Ini(pars_num);
    140         p_new[i].Ini(pars_num);
    141     }
    142 
    143     //-------------------------产生初始的随机种群--------------------------------
    144     int i;
    145     for (i = 0; i < Num; ++i)//对种群进行遍历
    146     {
    147         for (int j = 0; j < pars_num; ++j)//对参数列表进行遍历
    148             p_old[i].m_p_DNA[j] = Rand_Double()*(max - min) + min;
    149         p_old[i].m_f = p_fun->Compute(p_old[i].m_p_DNA);
    150     }
    151 
    152     CIndividual ind_best;
    153     ind_best.Ini(pars_num);
    154 
    155     for (int t = 0; t < T; ++t)//开始一代一代地进化
    156     {
    157         //显示结果
    158         ind_best = p_old[0];
    159         for (int i = 1; i < Num; ++i)
    160         {
    161             if (pos == true && ind_best.m_f < p_old[i].m_f)//求最大值
    162                 ind_best = p_old[i];
    163             else if (pos == false && ind_best.m_f > p_old[i].m_f)//求最小值
    164                 ind_best = p_old[i];
    165         }
    166         cout << ind_best << "
    ";
    167 
    168         //差分变异
    169         for (i = 0; i < Num; ++i)//对种群进行遍历
    170         {
    171             //产生三个随机数
    172             int x1, x2, x3;
    173             x1 = rand() % Num;
    174             do
    175             {
    176                 x2 = rand() % Num;
    177             } while (x1 == x2);
    178             do
    179             {
    180                 x3 = rand() % Num;
    181             } while (x1 == x3 || x2 == x3);
    182 
    183             for (int j = 0; j < pars_num; ++j)//对参数列表进行遍历
    184             {
    185                 p_new[i].m_p_DNA[j] = p_old[x1].m_p_DNA[j] + zoom * (p_old[x2].m_p_DNA[j] - p_old[x3].m_p_DNA[j]);
    186                 if (p_new[i].m_p_DNA[j]<min || p_new[i].m_p_DNA[j]>max)//越界
    187                     p_new[i].m_p_DNA[j] = p_old[i].m_p_DNA[j];
    188             }
    189         }
    190 
    191         //交叉操作,注意,交叉要对每个实数位进行交叉
    192         for (i = 0; i < Num; ++i)//对种群进行遍历
    193         {
    194             for (int j = 0; j < pars_num; ++j)
    195             {
    196                 if (Rand_Double() > cr)//不交叉
    197                     p_new[i].m_p_DNA[j] = p_old[i].m_p_DNA[j];
    198             }
    199             p_new[i].m_f = p_fun->Compute(p_new[i].m_p_DNA);
    200         }
    201 
    202         //选择操作
    203         for (i = 0; i < Num; ++i)//对种群进行遍历
    204         {
    205             if (pos == true && p_new[i].m_f < p_old[i].m_f)//求最大值
    206                 p_new[i] = p_old[i];
    207             else if (pos == false && p_new[i].m_f > p_old[i].m_f)//求最小值
    208                 p_new[i] = p_old[i];
    209         }
    210 
    211         //交换
    212         CIndividual *p_tmp;
    213         p_tmp = p_old;
    214         p_old = p_new;
    215         p_new = p_tmp;
    216         //此时,新种群的值被保存到p_old中
    217     }
    218 
    219     return 0;
    220 }
  • 相关阅读:
    Delphi命名规则
    highcharts 折线,饼状,条状综合图
    Highcharts创建一个简单的柱状图
    创建一个简单的WCF程序
    VS快捷键大全
    2021.05.28 手写简易web服务器
    2021.05.23 春眠不觉晓,optional知多少……
    springboot整合ActiveMQ实现异步交易
    安利一款云容器管理工具portainer……
    uglifyjs压缩js文件(指令压缩/ 批量压缩/ 编程方式压缩)
  • 原文地址:https://www.cnblogs.com/zhanjiahui/p/11181821.html
Copyright © 2011-2022 走看看