📄 antcolony.cpp
字号:
// Antcolony.cpp: implementation of the Antcolony class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "1.h"
#include "Antcolony.h"
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <fstream.h>
#include <stdio.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
double const c=1e-5;
double const Q=1e-3;
double const p=0.60;
double const a0=0.2;
double const b0=0.4;
Antcolony::Antcolony()
{
/* 初始化随机种子 */
srand((unsigned)time(NULL));
m_randseed = double((rand()%10000)/10000.0);
m_number=2;
m_enum=20.0;
m_ant=20;
m_precision=2.0;
m_sign=-2;
m_maxscope[0]=2.0;
m_maxscope[1]=2.0;
m_minscope[0]=-2.0;
m_minscope[1]=-2.0;
m_sumcut=0.0;//离差平方和
int i,j;
for(i=0;i<10;i++)
m_value[i]=1e-4;
/*将各个蚂蚁随机选择所有的参数且仅每个参数仅选择一个块*/
for(i=0;i<=m_enum;i++)//第i个蚂蚁
for(j=0;j<m_number;j++)
m_row[i][j]=randomint(0,m_enum+1); //第i个蚂蚁第j个参数所占的行数;
/*初始化变化信息素*/
for(i=0;i<=m_enum;i++)
for( j=0;j<m_number;j++)
m_deltapheromne[i][j]=c;
/*初始化信息素*/
for(i=0;i<=m_enum;i++)
for(j=0;j<m_number;j++)
m_pheromne[i][j]=c;
/*计算每个参数的步长*/
for(i=0;i<m_number;i++)
m_averagescope[i]=(abs(m_maxscope[i])+abs(m_minscope[i]))/m_enum;
/*计算每个块的数值大小*/
for(i=0;i<=m_enum;i++)
for(j=0;j<m_number;j++)
m_block[i][j]=m_averagescope[j]*i+m_minscope[j];
}
Antcolony::~Antcolony()
{
}
/*在整数low和high之间产生一个随机整数*/
int Antcolony::randomint(int low, int high)
{
int medium;
medium = (int)((randomperc(&m_randseed)*(high-low))+low);
return(medium);
}
/*产生0到1 之间均匀分布的随机数*/
double Antcolony::randomperc(double *seed)
{
//r双精度实型变量指针。该指针指向的单元存放随机数的种子;返回一个新值。
//但是本函数返回的不是r
int m;
double s,u,v;
double result;
s = 65536.0;
u = 2053.0;
v = 13849.0;
m = (int)(*seed/s);
*seed = *seed-m*s;
*seed = u*(*seed)+v;
m = (int)(*seed/s);
*seed = *seed-m*s;
result = *seed/s;
return(result);
}
/*函数*/
double Antcolony::f(double a, double b)
{
double temp=0.0;
double a1,a2,a3,a4,a5,a0;
a0=b*b*b*b*b;
a1=3*(1-a)*(1-a);
a3=10*(a/5.0-a*a*a-a0);
a2=exp(-a*a-(b+1)*(b+1));
a4=(1/3.0)*exp(-(a+1)*(a+1)-b*b);
a5=exp(-a*a-b*b);
temp=a1*a2-a3*a5-a4;
//temp=3*pow((1-a),2)*exp(-a*a-(b+1)*(b+1)-10*(a/5.0-a*a*a-pow(b,5)))-10*(a/5.0-a*a*a-pow(b,5))*exp(-a*a-b*b)-exp(-(a+1)*(a+1)-b*b)/3.0;
return temp;
}
/*计算所有蚂蚁周游一遍后的函数值*/
void Antcolony::fvalue()
{
int i,j;
double temp0[21][2];//第i个蚂蚁中第j个参数的值
for(i=0;i<=m_ant;i++)
{
for(j=0;j<m_number;j++)
{
temp0[i][j]=m_block[m_row[i][j]][j];
}
m_fvalue[i]=f(temp0[i][0],temp0[i][1]); //第i个蚂蚁周游一遍的函数值,假设是两参数的函数
}
}
/*计算所求得的离差平方和,以便确定计算终止条件*/
/*void Antcolony::sumcut()
{
int i;
double m_temp0=0.0;
double unityvalue;
fvalue();
for(i=0;i<m_ant;i++) //m_ant<m_enum
m_temp0=m_temp0+m_fvalue[i];
unityvalue=m_temp0/m_ant;
for(i=0;i<m_ant;i++)
{
fvalue();
m_sumcut=m_sumcut+(m_fvalue[i]-unityvalue)*(m_fvalue[i]-unityvalue);
}
}*/
/* 针对块的信息素的更新*/
void Antcolony::pheromne()//m为蚂蚁序号,n为参数个数
{
int i,j;
double m_sumaffect[21][2];//每个因子的总影响度,即为KA1=Y1+Y2+Y3
for(i=0;i<=20;i++) //初始化
for(j=0;j<2;j++)
m_sumaffect[i][j]=0.0;
fvalue();
for(i=0;i<m_ant;i++)
for(j=0;j<m_number;j++)
{ //每个因子的总的影响度
m_sumaffect[m_row[i][j]][j]=m_sumaffect[m_row[i][j]][j]+exp(-10+m_fvalue[i]);
m_deltapheromne[m_row[i][j]][j]=m_sumaffect[m_row[i][j]][j]*Q;
}
for(i=0;i<m_enum;i++)
for(j=0;j<m_number;j++)
m_pheromne[i][j]=m_deltapheromne[i][j]+p*m_pheromne[i][j];
}
/*能见度*/
void Antcolony::seescope()//m为蚂蚁序号,n为参数个数
{
int i,j;
double m_numrepeat[21][2];//一个因子重复的次数
double m_sumnum=0.0;//总共计算出的函数值的次数总和
double m_sumall=0.0;//函数值的总和
double m_unity;//总的函数值的平均值
double m_sumaffect[21][2];//每个因子的总影响度,即为KA1=Y1+Y2+Y3 :数理统计p152 L4
for(i=0;i<=20;i++) //初始化
{
for(j=0;j<2;j++)
{
m_numrepeat[i][j]=0.0;
m_sumaffect[i][j]=0.0;
m_tempaffect[i][j]=0.0;
}
}
fvalue();
for(i=0;i<=m_ant;i++)
{
for(j=0;j<m_number;j++)
{
m_sumaffect[m_row[i][j]][j]=m_sumaffect[m_row[i][j]][j]+exp(-10+m_fvalue[i]);//每个因子的总的影响度
m_numrepeat[m_row[i][j]][j]++;//每个因子重复出现的次数
}
}
for(i=0;i<=m_ant;i++)
for(j=0;j<m_number;j++)
if(m_numrepeat[i][j]>0)
m_tempaffect[i][j]=m_sumaffect[i][j]/m_numrepeat[i][j];
else
m_tempaffect[i][j]=0;
//每个因子的试验值,即kA1=KA1/3.0
//计算总的函数值的次数,计算总的函数值
for(i=0;i<m_ant;i++)
for(j=0;j<m_number;j++)
m_sumall=m_sumall+m_sumaffect[i][j];
//总平均数为
// m_unity=m_sumall/m_ant;
//计算每个因子的影响度
for(i=0;i<m_enum;i++)
for(j=0;j<m_number;j++)
//QA=3*(kA1-Yp)*(kA1-Yp)
m_affect[i][j]=m_tempaffect[i][j]/m_sumall;
//m_numrepeat[i][j]*pow((m_tempaffect[i][j]-m_unity),2);
}
/*蚂蚁的转移概率*/
void Antcolony::ptrans()
{
int i,j;
double m_sumaffect;
double m_tempp[21][2];
for(i=0;i<=20;i++)//初始化
for(j=0;j<=2;j++)
m_tempp[i][j]=0.0;
m_sumaffect=0.0;
seescope();
pheromne();
for(i=0;i<m_enum;i++)
{
for(j=0;j<m_number;j++)
{
m_tempp[i][j]=pow(m_pheromne[i][j],a0)*pow(m_affect[i][j],b0);
m_sumaffect=m_sumaffect+m_tempp[i][j];
}
}
for(i=0;i<m_number;i++)
for(j=0;j<m_enum;j++)
m_ptrans[i][j]=m_tempp[i][j]/m_sumaffect;
}
/*蚂蚁依据概率周游*/
void Antcolony::travel()
{
int i,j,k,l;
for(i=0;i<=m_ant;i++)
{
for(j=0;j<m_number;j++)
{
int m_tempant=-2;//临时定义变量存储数据
while(m_tempant<-1)//保证能够取一个值,且仅取一个值
{
for(l=0;l<=m_enum,m_tempant<-1;l++)
{
double pr;//随机概率
srand((unsigned)time(NULL));
pr = double((rand()%1000)/1000.0);
ptrans();
if(pr<=m_ptrans[l][j])
{
m_row[i][j]=l; //得到参数的块的更新
m_tempant++;
}
}
}
}
}
}
/*当蚂蚁停止周游时,求出最大函数值,即为所求参数取值和函数值*/
void Antcolony::Antalgorithm()
{
int i;
double m_max=1e-4;
// sumcut();//离差平方和
int time=0;
while(time<50)
{
travel();
// sumcut();
time++;
}
// f1=f(-0.0093,1.5814);
/* fvalue();
for(i=0;i<m_ant;i++)
for(j=0;j<m_number;j++)
{
m_row[i][j];
if(m_fvalue[i]>m_max)
{
m_max=m_fvalue[i];
m_sign=i;
}
} */
// for(i=0;i<m_number;i++)
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -