差分进化算法(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 ...
随机推荐
- 面试系列24 dubbo负载均衡策略和集群容错策略
(1)dubbo负载均衡策略 1)random loadbalance 默认情况下,dubbo是random load balance随机调用实现负载均衡,可以对provider不同实例设置不同的权重 ...
- 窥探C语言程序的编译、链接与.h文件
概述 C语言程序从源文件经过编译.链接生成可执行文件.那么编译与链接分别做了什么? 开发中为什么使用.h编写函数的声明?接下来使用案例说清楚为什么这样编写代码. C语言程序的编译和链接 C语言程序从源 ...
- Luogu P4246 [SHOI2008]堵塞的交通(线段树+模拟)
P4246 [SHOI2008]堵塞的交通 题意 题目描述 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个\(2\)行\(C\)列的矩形 ...
- Django流程
开始具体的代码之旅前,先来宏观地看下Django是如何处理Http Resquest的,如下图: 假设你已经在浏览器输入了 http://127.0.0.1:8000/polls/,接下来浏览器会把请 ...
- SoapUI测试接口【转】
下载安装soapUI工具,具体安装按照提示往下走就可以,这里不着重说明,下面是我打开soapUI工具的起始窗口: 在Projects上鼠标右键点击,选择new soap project(新建一个SO ...
- Vim ---- 默认打开行号
Vim有非常迅速跳转到某一行行首的方法,例如 :n 或者 nG,n 表示到第 n 行. 但是Vim的显示行号功能默认是关闭的. 可用一下方法使Vim默认显示行号: 在配置文件 .vimrc 中,输入 ...
- 【五校联考5day1】登山
题目 描述 题目大意 给你一个n∗nn*nn∗n的网格图.从(0,0)(0,0)(0,0)开始,每次只可以向右或向上移动一格,并且不能越过对角线(即不能为x<yx<yx<y). 网格 ...
- RabbitMQ 五种工作模式
官网介绍:https://www.rabbitmq.com/getstarted.html 五种工作模式的主要特点 简单模式:一个生产者,一个消费者 work模式:一个生产者,多个消费者,每个消费者获 ...
- linux 每天一个命令
Nginx [emerg]: bind() to 0.0.0.0:80 failed (98: Address already in use) 使用命令关闭占用80端口的程序 sudo fuser ...
- OpenCASCADE圆与平面求交
OpenCASCADE圆与平面求交 eryar@163.com 在 解析几何求交之圆与二次曲面中分析了OpenCASCADE提供的类IntAna_IntConicQuad可以用来计算圆与二次曲面之间的 ...