📄 acs4fun.cpp
字号:
#include "acs4fun.h"
#include <time.h>
#include <stdlib.h>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
using namespace std;
CAcs4Fun::CAcs4Fun(int pNIters,int pNLayers,int ppointpos,int pNAnts,
int pNoFun,int pRadix, double pPSelMax, double pAlpha,
double pRho,double pTau0)
{
int i,j;
char filename[40];
char t[11];
double tt;
time_t time1;
NIters=pNIters;
NAnts=pNAnts;
Radix=pRadix;
PSelMax=pPSelMax;
Alpha=pAlpha;
Rho=pRho;
Tau0=pTau0;
pointpos=ppointpos;
pointpos=0; //暂时改为强制pointpos=0,自变量范围由xmin,xmax决定
/*
xmin=0;xmax=1;xmin_t=0;xmax_t=1;
ymin=0;ymax=1;ymin_t=0;ymax_t=1; //这样的设置等价于不做变换
*/
NoFun=pNoFun;
setfun(NoFun); //该函数会设置好NVariants之类的值
NLayers=pNLayers*NVariants;
//srand((unsigned int)time(NULL));
NRecordedResults=0;
//////// 为ant fit ph globalbestant y x x_real globalbestx globalbestx_real
//////// 分配空间(在析构函数中才会释放)
ant=(int **)calloc(sizeof(int*),NAnts);
for (i=0;i<NAnts;i++)
ant[i]=(int*)calloc(sizeof(int),NLayers);
fit=(double*)calloc(sizeof(double),NAnts);
ph=(double **)calloc(sizeof(double *),NLayers);
for (i=0;i<NLayers;i++)
ph[i]=(double*)calloc(sizeof(double),Radix);
globalbestant=(int *)calloc(sizeof(int),NLayers);
y=(double *)calloc(sizeof(double),NAnts);
x=(double **)calloc(sizeof(double*),NAnts);
x_real=(double **)calloc(sizeof(double *),NAnts);
for (i=0;i<NAnts;i++)
{
x[i]=(double *)calloc(sizeof(double),NVariants);
x_real[i]=(double *)calloc(sizeof(double),NVariants);
}
globalbestx=(double *)calloc(sizeof(double),NVariants);
globalbestx_real=(double *)calloc(sizeof(double),NVariants);
globalbestfit=MAX_FIT_ALLOWED;
bestiter=0;
if(USE_CHAOS==1)
{
chaos_last_val=(double *)calloc(sizeof(double),NLayers);
//设置混沌序列初值
for(i=0;i<NLayers;i++)
chaos_last_val[i]=(double)CHAOS_INIT_VAL+0.000001*i;
}
if(CHAOTIC_SEARCH==1)
{
cs_last_val=(double *)calloc(sizeof(double),NVariants);
cx=(double *)calloc(sizeof(double),NVariants);
localbestx=(double *)calloc(sizeof(double),NVariants);
cx_real=(double *)calloc(sizeof(double),NVariants);
localbestx_real=(double *)calloc(sizeof(double),NVariants);
/*
//设置混沌序列初值
tt=(double)rand()/RAND_MAX;
//while (fabs((tt-0.25)*(tt-0.5)*(tt-0.75))<0.05)
while (fabs(tt-0.25)<0.05||fabs(tt-0.5)<0.05 || fabs(tt-0.75)<0.05)
tt=(double)rand()/RAND_MAX;
for (i=0;i<NVariants;i++)
if(RANDOM_SEARCH==1)
cs_last_val[i]=rand()/RAND_MAX;
else
{
cs_last_val[i]=tt+0.0001*i;
//cs_last_val[i]=CHAOS_INIT_VAL+0.0001*i;
}
*/
}
// initvars(); //改为在start()中进行初始化变量值的步骤
//////////////////打开记录结果用的文件///////////////
strcpy(filename,"Record_");
itoa(NoFun,t,10);
strcat(filename,t);
time( &time1 ); // Get time in seconds
ltoa(time1,t,10);
strcat(filename,"_");
strcat(filename,t);
strcat(filename,".txt");
fout=fopen(filename,"w");
}
CAcs4Fun::~CAcs4Fun()
{
int i;
for (i=0;i<NAnts;i++)
free(ant[i]);
free(ant);
free(fit);
for (i=0;i<NLayers;i++)
free(ph[i]);
free(ph);
free(globalbestant);
free(y);
for (i=0;i<NVariants;i++)
{
free(x[i]);
free(x_real[i]);
}
free(x);
free(x_real);
free(globalbestx);
free(globalbestx_real);
if(USE_CHAOS==1)
free(chaos_last_val);
if(CHAOTIC_SEARCH==1)
{
free(cs_last_val);
free(cx);
free(localbestx);
free(cx_real);
free(localbestx_real);
}
if(bWriteResult==true)
fclose(fout);
}
void CAcs4Fun::Chaotic_Search(int NoAnt, int iter)
{
//在以NoAnt这只蚂蚁所在点为中心,radius为半径的区域内做混沌搜索
//如果搜索到优于这只蚂蚁对应的解就用新搜索到的替换原来这只蚂蚁
double radius,t,localbestfit,cfit;
double kx=(xmax_t-xmin_t)/(xmax-xmin);
double ky=(ymax_t-ymin_t)/(ymax-ymin);
static int NLayersPerVariant=NLayers/NVariants;
int i,j;
if(pointpos!=0)
{
printf("Chaotic Search is not fit for problems with pointpos!=0\n");
return;
}
else
{
// cs_last_val=CHAOS_INIT_VAL;
switch(RATIO_FUN)
{
case 0:
radius=exp(-0.01*iter); //这个变量好像取名为直径要好些,不过这个关系不大
break;
case 1:
radius=1.0-1.0/(1.0+exp(-0.02*iter*NIters/1000+4));
if(radius<pow(10.0,-(double)(NLayers/NVariants-2)))
radius=pow(10.0,-(double)(NLayers/NVariants-2));
break;
case 2:
if(iter>50)
radius=exp(-0.01*iter);
else
radius=1;
break;
case 3:
if(iter<=100)
radius=1;
else
{
if(iter>=700)
radius=0.00001;
else
radius=(700.0-iter)/600.0;
}
break;
default:
radius=1.0-1.0/(1.0+exp(-0.02*iter+4));
break;
}
// retval=x[NoAnt];
localbestfit=globalbestfit; ////!!!!!!!!!!!
for(i=0;i<CHAOTIC_CYCLE;i++)
{
for(j=0;j<NVariants;j++)
{
t=globalbestx[j]+radius*(cs_last_val[j]-0.5); ///!!!!!!!!!!!!!!!
if(t>=1)
t=t-1;
else
if(t<0)
t=t+1;
cx[j]=t;
cx_real[j]=(t-xmin)*kx+xmin_t;
}
cfit=(f(cx_real)-ymin)*ky+ymin_t;
if(cfit<localbestfit)
{
localbestfit=cfit;
for(j=0;j<NVariants;j++)
{
localbestx[j]=cx[j];
localbestx_real[j]=cx_real[j];
}
}
for(j=0;j<NVariants;j++)
{
if(RANDOM_SEARCH==1)
cs_last_val[j]=rand()/RAND_MAX;
else
cs_last_val[j]=CHAOS_MU*cs_last_val[j]*(1-cs_last_val[j]);
}
}
//以上操作将完成指定次数的混沌搜索,下面将根据得到的结果修改最优蚂蚁经过的路径
if(localbestfit<globalbestfit) /////!!!!!!!!!!!!!
{
//找到了更优的路径,则替换原最优蚂蚁
y[NoAnt]=f(localbestx_real);
fit[NoAnt]=localbestfit;
for (j=0;j<NVariants;j++)
{
x_real[NoAnt][j]=localbestx_real[j];
x[NoAnt][j]=localbestx[j];
for(i=0;i<NLayersPerVariant;i++)
{
localbestx[j]=localbestx[j]*10;
ant[NoAnt][j*NLayersPerVariant+i]=(int)localbestx[j];
if(ant[NoAnt][j*NLayersPerVariant+i]>=10 || ant[NoAnt][j*NLayersPerVariant+i]<0)
printf("Error!\n");
localbestx[j]=localbestx[j]-(int)localbestx[j];
}
}
}
}
}
double CAcs4Fun::Random(int AntNo=-1)
{
double retval;
// static double old_retval=CHAOS_INIT_VAL;
if(USE_CHAOS==1 && AntNo!=-1)
{
retval=chaos_last_val[AntNo]*(1-chaos_last_val[AntNo])*CHAOS_MU;
chaos_last_val[AntNo]=retval;
}
else
retval=(double)rand()/RAND_MAX;
return retval;
}
void CAcs4Fun::initvars()
{
int i,j;
double tt;
////////初始化ant fit ph中的值
for(i=0;i<NAnts;i++)
for (j=0;j<NLayers;j++)
ant[i][j]=0;
for (i=0;i<NAnts;i++)
{
for (j=0;j<NVariants;j++)
{
x[i][j]=0;
x_real[i][j]=0;
}
y[i]=0;
fit[i]=0;
}
for (i=0;i<NVariants;i++)
{
globalbestx[i]=0;
globalbestx_real[i]=0;
}
for (i=0;i<NLayers;i++)
{
globalbestant[i]=0;
for (j=0;j<Radix;j++)
ph[i][j]=Tau0;
}
if(CHAOTIC_SEARCH==1)
{
for (i=0;i<NVariants;i++)
{
cx[i]=0;
localbestx[i]=0;
cx_real[i]=0;
localbestx_real[i]=0;
}
//设置混沌序列初值
tt=(double)rand()/RAND_MAX;
while (fabs(tt-0.25)<0.05||fabs(tt-0.5)<0.05 || fabs(tt-0.75)<0.05)
//while (fabs((tt-0.25)*(tt-0.5)*(tt-0.75))<0.05)
tt=(double)rand()/RAND_MAX;
for (i=0;i<NVariants;i++)
if(RANDOM_SEARCH==1)
cs_last_val[i]=rand()/RAND_MAX;
else
{
cs_last_val[i]=tt+0.0001*i;
//cs_last_val[i]=CHAOS_INIT_VAL+0.0001*i;
}
}
globalbestfit=MAX_FIT_ALLOWED;
bestiter=0;
}
void CAcs4Fun::WriteResult2(int NoAnt)
{
// int i;
// for (i=0;i<NAnts;i++)
// {
fprintf(fout,"%.16f\n",y[NoAnt]);
// }
// fprintf(fout,"\n");
}
void CAcs4Fun::start()
{
int iter,layer,curant,i,j;
double t,tt;
int t1,t2;
bool s=false;
struct tm *newtime;
time_t starttime;
time_t endtime;
initvars();
///////////去掉混沌序列的前面几个值
// if(USE_CHAOS==1)
// for (i=0;i<NLayers;i++)
// for (j=0;j<30;j++)
// Random(i);
///////////////////输出一些参数信息到文件///////////////////
time( &starttime ); // Get time in seconds
newtime = localtime( &starttime ); // Convert time to struct tm form
if(bWriteResult==true)
{
if(bWriteAllData==false)
{
fprintf(fout,"***********************************************************************************\n");
fprintf(fout,"Time = %s\n",asctime(newtime));
fprintf(fout,"MaxIter = %d,\tNLayers = %d,\tpNAnts = %d,\tNoFun = %d,\tRadix = %d\n",NIters,NLayers,NAnts,NoFun,Radix);
fprintf(fout,"PSelMax = %f,\tAlpha = %f,\tRho = %f,\tTau0 = %f\n",PSelMax,Alpha,Rho,Tau0);
fprintf(fout,"***********************************************************************************\n");
}
else
{
/////////////////输出全部数据,不输出时间之类的信息,以方便matlab处理
}
}
////////////////////////////////////////////////////////////
for(iter=0;iter<NIters;iter++)
{
for(layer=0;layer<NLayers;layer++)
{
///////for each ant, build a tour
for(curant=0;curant<NAnts;curant++)
{
t=Random(-1);
if(t<PSelMax)
{
///select the city with maximum pheromone
t2=0;
for (t1=1;t1<Radix;t1++)
if(ph[layer][t1]>ph[layer][t2])
t2=t1;
ant[curant][layer]=t2;
}
else
{
t=Random(layer);
tt=0;
for (t1=0;t1<Radix;t1++)
tt+=ph[layer][t1];
t=t*tt;
for (t1=0;t1<Radix;t1++)
if(ph[layer][t1]>t)
break;
else
t-=ph[layer][t1];
if(t1==Radix)
t2=Radix-1;
else
t2=t1;
ant[curant][layer]=t2;
}
////////////////local update
ph[layer][ant[curant][layer]]=(1-Rho)*ph[layer][ant[curant][layer]]+Rho*Tau0;
}
}
/////////////// all the ants have finished tour construction
/////////////// the following function call will calculate the fitness of them
calcfit();
/////////////////////////////////////////////////////////////
/////////////// find out the best ant
t2=0;
for (t1=1;t1<NAnts;t1++)
if(fit[t1]<fit[t2])
t2=t1;
/////////////////////////chaotic search, local update will not to be done with the solution
/////////////////////////generated by chaotic search!!!!
if(CHAOTIC_SEARCH==1)
Chaotic_Search(t2,iter);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -