差分进化算法(DE)的C++面向对象方法实现
代码来源于网络,写得非常棒
/*DE_test
*对相应的Matlab程序进行测试
*/ #include <iostream>
#include <cmath>
#include <ctime>
using namespace std; //产生随机数,随机数为(0.0,1.0)
double Rand_Double(void)
{
return static_cast<double>(rand()) / static_cast<double>(RAND_MAX);
} //测试函数Hansen
//参数个数为2
double Hansen(double *p_pars)
{
return (cos(1.0) + 2.0*cos(p_pars[] + 2.0) + 3.0*cos(2.0*p_pars[] + 3.0)
+ 4.0*cos(3.0*p_pars[] + 4.0) + 5.0*cos(4.0*p_pars[] + 5.0))
* (cos(2.0*p_pars[] + 1.0) + 2.0*cos(3.0*p_pars[] + 2.0) +
3.0*cos(4.0*p_pars[] + 3.0) + 4.0*cos(5.0*p_pars[] + 4.0) + 5.0*cos(6.0*p_pars[] + 5.0));
} class CFunction
{
public:
void *m_p_fun;//指向测试函数的指针
int m_pars_num;//参数个数
double m_min;//下限
double m_max;//上限
bool m_pos;//求解最小值还是最大值,如果是最小值则m_pos为false,如果是最大值则m_pos为true
public:
CFunction(void *p_fun, int pars_num, double min, double max, bool pos)
:m_p_fun(p_fun), m_pars_num(pars_num), m_min(min), m_max(max), m_pos(pos)
{
} virtual double Compute(double *p_pars) = ;
}; class CHansen :public CFunction
{
public:
//注册函数
CHansen(void)
:CFunction(Hansen, , -10.0, 10.0, false)
{
} double Compute(double *p_pars)
{
return Hansen(p_pars);
}
}; //个体
class CIndividual
{
public:
double *m_p_DNA;//参数
double m_f;//适应值
int m_DNA_length;//DNA的长度 public:
CIndividual(void)
:m_f(0.0), m_DNA_length(), m_p_DNA(NULL)
{
} ~CIndividual(void)
{
if (m_p_DNA != NULL)
delete[] m_p_DNA;
} //初始化,分配内存空间
void Ini(int pars_num)
{
m_DNA_length = pars_num;
m_p_DNA = new double[m_DNA_length];
} //假定两者分配的内存空间的大小一样
CIndividual& operator=(CIndividual& ind)
{
m_f = ind.m_f;
//m_DNA_length = ind.m_DNA_length;
for (int i = ; i < m_DNA_length; ++i)
{
m_p_DNA[i] = ind.m_p_DNA[i];
}
return *this;
} friend ostream& operator<<(ostream& o, CIndividual& ind)//运算符重载
{
return o << ind.m_f;
}
}; int main()
{
//---------------------------设置随机数------------------------------------
srand((unsigned int)(time(NULL))); //获得参数
int Num, T;
double zoom, cr; cout << "种群大小:";
cin >> Num; cout << "进化代数:";
cin >> T; cout << "缩放因子:";
cin >> zoom; cout << "交叉因子:";
cin >> cr; //----------------------对函数进行操作,注册函数------------------------------
CHansen fun_Hansen; CFunction *p_fun = &fun_Hansen;//为了实现多态
int pars_num = p_fun->m_pars_num;//参数个数
double min = p_fun->m_min;//下限
double max = p_fun->m_max;//上限
bool pos = p_fun->m_pos;//求最大值还是最小值 //----------------------注册种群,并分配内存空间-----------------------------
CIndividual *p_old = new CIndividual[Num];
CIndividual *p_new = new CIndividual[Num];
for (int i = ; i < Num; ++i)
{
p_old[i].Ini(pars_num);
p_new[i].Ini(pars_num);
} //-------------------------产生初始的随机种群--------------------------------
int i;
for (i = ; i < Num; ++i)//对种群进行遍历
{
for (int j = ; j < pars_num; ++j)//对参数列表进行遍历
p_old[i].m_p_DNA[j] = Rand_Double()*(max - min) + min;
p_old[i].m_f = p_fun->Compute(p_old[i].m_p_DNA);
} CIndividual ind_best;
ind_best.Ini(pars_num); for (int t = ; t < T; ++t)//开始一代一代地进化
{
//显示结果
ind_best = p_old[];
for (int i = ; i < Num; ++i)
{
if (pos == true && ind_best.m_f < p_old[i].m_f)//求最大值
ind_best = p_old[i];
else if (pos == false && ind_best.m_f > p_old[i].m_f)//求最小值
ind_best = p_old[i];
}
cout << ind_best << "\n"; //差分变异
for (i = ; i < Num; ++i)//对种群进行遍历
{
//产生三个随机数
int x1, x2, x3;
x1 = rand() % Num;
do
{
x2 = rand() % Num;
} while (x1 == x2);
do
{
x3 = rand() % Num;
} while (x1 == x3 || x2 == x3); for (int j = ; j < pars_num; ++j)//对参数列表进行遍历
{
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]);
if (p_new[i].m_p_DNA[j]<min || p_new[i].m_p_DNA[j]>max)//越界
p_new[i].m_p_DNA[j] = p_old[i].m_p_DNA[j];
}
} //交叉操作,注意,交叉要对每个实数位进行交叉
for (i = ; i < Num; ++i)//对种群进行遍历
{
for (int j = ; j < pars_num; ++j)
{
if (Rand_Double() > cr)//不交叉
p_new[i].m_p_DNA[j] = p_old[i].m_p_DNA[j];
}
p_new[i].m_f = p_fun->Compute(p_new[i].m_p_DNA);
} //选择操作
for (i = ; i < Num; ++i)//对种群进行遍历
{
if (pos == true && p_new[i].m_f < p_old[i].m_f)//求最大值
p_new[i] = p_old[i];
else if (pos == false && p_new[i].m_f > p_old[i].m_f)//求最小值
p_new[i] = p_old[i];
} //交换
CIndividual *p_tmp;
p_tmp = p_old;
p_old = p_new;
p_new = p_tmp;
//此时,新种群的值被保存到p_old中
} return ;
}
差分进化算法(DE)的C++面向对象方法实现的更多相关文章
- 标准差分进化算法matlab程序实现(转载)
标准差分进化算法matlab程序实现 自适应差分演化算法方面的Matlab和C++代码及论文 差分进化算法 DE-Differential Evolution matlab练习程序(差异演化DE) [ ...
- 差分进化算法 DE-Differential Evolution
差分进化算法 (Differential Evolution) Differential Evolution(DE)是由Storn等人于1995年提出的,和其它演化算法一样,DE是一种模拟生物进化 ...
- 差分进化算法介绍及matlab实现
引言 差分进化算法是基于群体智能理论的优化算法,是通过群体内个体间的合作与竞争而产生的智能优化搜索算法,它保留了基于种群的全局搜索策略,采用实数编码.基于差分的简单变异操作和"一对一&quo ...
- 离散的差分进化Discrete DE
一般的差分算法的变异规则:Xmutation=Xr1+F(Xr2-Xr3),F为缩放因子, 离散差分进化DDE的变异规则:设每个解为K个元素的集合,则Xr2-Xr3:求出Xr2与Xr3有m个共同元素, ...
- 差分进化算法-python实现
DEIndividual.py import numpy as np import ObjFunction class DEIndividual: ''' individual of differen ...
- Python遗传和进化算法框架(一)Geatpy快速入门
https://blog.csdn.net/qq_33353186/article/details/82014986 Geatpy是一个高性能的Python遗传算法库以及开放式进化算法框架,由华南理工 ...
- SBX(Simulated binary crossover)模拟二进制交叉算子和DE(differential evolution)差分进化算子
一起来学演化计算-SBX(Simulated binary crossover)模拟二进制交叉算子和DE(differential evolution)差分进化算子 觉得有用的话,欢迎一起讨论相互学习 ...
- [Evolutionary Algorithm] 进化算法简介
进化算法,也被成为是演化算法(evolutionary algorithms,简称EAs),它不是一个具体的算法,而是一个“算法簇”.进化算法的产生的灵感借鉴了大自然中生物的进化操作,它一般包括基因编 ...
- geatpy - 遗传和进化算法相关算子的库函数(python)
Geatpy The Genetic and Evolutionary Algorithm Toolbox for Python Introduction Website (including doc ...
随机推荐
- DNS配置-BIND安装配置全过程
下载地址:ftp://ftp.isc.org/isc/ 下载bind,我下载的是bind-9.11.13.tar.gz 我下载的文件放在/root目录下进入目录解压缩 [root@localhost ...
- <Python基础>python是如何进行内存管理的
.Python 是如何进行内存管理的?答:从三个方面来说,一对象的引用计数机制,二垃圾回收机制,三内存池机制⒈对象的引用计数机制Python 内部使用引用计数,来保持追踪内存中的对象,所有对象都有引用 ...
- Spring父子上下文(WebApplicationContext)(防止事务失效)
如果你使用了listener监听器来加载配置,一般在Struts+Spring+Hibernate的项目中都是使用listener监听器的.如下 <listener> <listen ...
- JS时间比较大小
目录 1. 时间比较 2. 时间戳比较 3. 日期比较方法 4. 参考 1. 时间比较 var curTime = new Date(); //把字符串格式转化为日期类 var starttime = ...
- SpringBoot集成JPA根据实体类自动生成表
数据库是mysql,在application.properties中的写法如下: 原来配置这样的时候确实可以生产表的 #spring.jpa.hibernate.ddl-auto=update 多方查 ...
- CNN网络中的不变性理解
神经网络中的不变性 原文:https://blog.csdn.net/voxel_grid/article/details/79275637 个人认为cnn中conv层对应的是“等变性”(Eq ...
- Python全栈开发:装饰器实例
#!/usr/bin/env python # -*- coding;utf-8 -*- """ 1.将outer函数放入内存 2.遇见@ + 函数名,则将该函数转换为装 ...
- 介绍了Apache日志文件每条数据的请意义以及一些实用日志分析命令
这篇文章主要介绍了apache日志文件每条数据的请意义,以及一些实用日志分析命令,需要的朋友可以参考下(http://wap.0834jl.com) 一.日志分析 如果apache的安装时采用默认的配 ...
- LUOGU P1505 [国家集训队]旅游 (树链剖分+线段树)
传送门 解题思路 快被调死的码农题,,,其实就是一个边权下放到点权的线段树+树剖. #include<iostream> #include<cstdio> #include&l ...
- light oj 1095 组合数学
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> ...