⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mga.cpp

📁 这是一个基于多智能体的遗传算法
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <stdlib.h> 
#include <stdio.h> 
#include <math.h> 
#include <iostream.h>
#include <iomanip.h>
#include <time.h>
#include <windows.h>
#include <vector>
#include <algorithm>
#include "matlib.h" 
using namespace std;
#define IM1 2147483563
#define IM2 2147483399
#define AM (1.0/IM1)
#define IMM1 (IM1-1)
#define IA1 40014
#define IA2 40692
#define IQ1 53668
#define IQ2 52774
#define IR1 12211
#define IR2 3791
#define NTAB 32
#define NDIV (1+IMM1/NTAB)
#define EPS 1.2e-7
#define RNMX (1.0-EPS)
#define shiyingduchushizhi -6.67e66
#define PI 3.14159265358 
#define sl 3 //学习域的大小
#define szhongqun 9//学习种群的大小
#define smaxgen 10//学习次数
#define sR 0.2 //学习半径
#define spm 0.05//学习过程中的变异概率
#define lanmuteshuliang 5
#define PM 0.1
#define PC 0.1
#define wei 30
#define houdaishuliang 9
int MGA[9][4]={{1,1,1,1},{1,2,2,2},{1,3,3,3},{2,1,2,3},{2,2,3,1},{2,3,1,2},{3,1,3,2},{3,2,1,3},{3,3,2,1}};
int jishuqi=0;
int bianyitongji=0;
int jiaochatongji=0;
int yimintongji=0;
int jingzhengtongji=0;
int jingzhengtongji1=0;
int xuexitongji=0;
int jieweishu=30;
unsigned int seed=0; //seed 为种子,要设为全局变量 
void mysrand(long int i) //初始化种子 
{ 
seed = -i; 
} 
long a[1];
vector<double> zuo;//定义左边界数值
vector<double> you;//定义右边界数值
//设置全局变量
struct individual
{
	double *chrom;  //染色体;
	double geti[wei];//变量值
	double shiyingdu; //目标函数的值;
	double fitness;   //变换后的适应度值;
};
struct youxuan//确定交叉后的优选个体
{
	double geti[wei];//变量值
	double shiyingdu;
};
class gpji
{
public:
	double gpp[wei];
};
gpji gp[houdaishuliang];
bool cmpshiyingdujiang1(const individual &p1,const individual &p2)
{
	return ((p1.shiyingdu)>(p2.shiyingdu));
}
bool cmpshiyingdujiang2(const youxuan &p1,const youxuan &p2)
{
	return ((p1.shiyingdu)>(p2.shiyingdu));
}
int cmpgeti(const void *p1,const void *p2)
{
	float i=((individual *)p1)->geti[0];//现在是按照"个体值"排序
	float j=((individual *)p2)->geti[0];
	return i<j ? -1:(i==j ? 0:1);//现在是按升序牌排列,将1和-1互换后就是按降序排列
}
int cmpshiyingdu(const void *p1,const void *p2)
{
	float i=((individual *)p1)->shiyingdu;//现在是按照"个体"排序
	float j=((individual *)p2)->shiyingdu;
	return i<j ? 1:(i==j ? 0:-1);//现在是按jiang序牌排列,将1和-1互换后就是按sheng序排列
}
double ran1(long *idum)
{
int j;
long k;
static long idum2=123456789;
static long iy=0;
static long iv[NTAB];
float temp;
if (*idum <= 0) 
{ 
if (-(*idum) < 1) *idum=1;
else *idum = -(*idum);
idum2=(*idum);
for (j=NTAB+7;j>=0;j--) 
{ 
k=(*idum)/IQ1;
*idum=IA1*(*idum-k*IQ1)-k*IR1;
if (*idum < 0) *idum += IM1;
if (j < NTAB) iv[j] = *idum;
}
iy=iv[0];
}
k=(*idum)/IQ1; 
*idum=IA1*(*idum-k*IQ1)-k*IR1; 
 if (*idum < 0) *idum += IM1; 
k=idum2/IQ2;
idum2=IA2*(idum2-k*IQ2)-k*IR2; 
if (idum2 < 0) idum2 += IM2;
j=iy/NDIV;
iy=iv[j]-idum2;
iv[j] = *idum; 
if (iy < 1) iy += IMM1;
if ((temp=AM*iy) > RNMX) return RNMX; 
else return temp;
}
double gasdev(long *idum)
{	
	double ran1(long *idum);
	static int iset=0;
	static double gset;
	double fac,rsq,v1,v2;
	if (*idum < 0) 
		iset=0; //初始化
	if (iset == 0) 
	{
		do 
		{
			v1=2.0*ran1(idum)-1.0; 
			v2=2.0*ran1(idum)-1.0; 
			rsq=v1*v1+v2*v2; 
		}while (rsq >= 1.0 || rsq == 0.0);
		fac=sqrt(-2.0*log(rsq)/rsq);
		gset=v1*fac;
		iset=1;
		return v2*fac;
	} 
	else 
	{
		iset=0;
		return gset;
	}
}
class GA
{

public:
	GA(int mgen=700,vector<double> z=zuo,vector<double> y=you,int zhongqun=25,int weishu=jieweishu)
	{
		zuobianjie=z;
		youbianjie=y;
		maxgen=mgen;
		zhongqunshu1=zhongqun;
		jiedeweishu=weishu;
	}
	//函数	
	void initialize()
	{
		//shengchenggp();
		int i,j;
		gen=0;//起始代
		lchrom=8;//基因数量的初始化
		ar=ac=sqrt(zhongqunshu1);//域的大小
		nowpop=new individual[zhongqunshu1];//当代
		mysrand(time(0));//随机数种子
		a[0]=seed;//随机数种子
		//对最优个体的初始化
		for(i=0;i<jiedeweishu;i++)
		{
			zuiyougeti.geti[i]=0;
		}
		zuiyougeti.fitness=0;
	    zuiyougeti.shiyingdu=shiyingduchushizhi;
		vector<individual> hundunzhongqun(3e3);
		for(i=0;i<jiedeweishu;i++)
		{
			for(j=0;j<3e3;j++)
			{
				hundunzhongqun[j].geti[i]=zuobianjie[i]+(youbianjie[i]-(zuobianjie[i]))*ran1(a);//yindao;
			}
			

		}
		for(i=0;i<3e3;i++)
		{
			mubiaohanshu(hundunzhongqun[i]);
		}

	    sort(hundunzhongqun.begin(),hundunzhongqun.end(),cmpshiyingdujiang1);//根据适应度将初始种群集按降序进行排列
		if(hundunzhongqun[0].shiyingdu<hundunzhongqun[1].shiyingdu)
			system("pause");


			for(i=0;i<zhongqunshu1;i++)//产生初始种群
			{
				//for(j=0;j<jiedeweishu;j++)
				//{
					//nowpop[i].geti[j]=hundunzhongqun[i].geti[j];
				//}
				nowpop[i]=hundunzhongqun[i];
			}
			//guanjiancanshujisuan();
			jingyingbaoliu();	//精英保留的实现
			/*for(i=3e3-1;i>=0;i--)
			{
				delete [] hundunzhongqun[i].geti;
			}*/
	}
void jingyingbaoliu()	//精英保留的实现
{
	individual max=nowpop[0];
	for(int i=1;i<zhongqunshu1;i++)
	{
		if(max.shiyingdu<nowpop[i].shiyingdu)
		{
			max=nowpop[i];
		}
	}
	if(max.shiyingdu>zuiyougeti.shiyingdu)
	{
		zuiyougeti=max;//如果最优个体的shiyingdu比当代最大的shiyingdu小则用当代的代替之
	}
	else
		nowpop[rnd(0,(zhongqunshu1-1))]=zuiyougeti;//否则的话从当代中随机挑选一个用最优个体代替之
}

void guanjiancanshujisuan()//计算shiyingdu,根据shiyingdu计算sumshiyingdu,对shiyingdu进行尺度变换变成fitness,根据fitness计算sumfitness,avefitness,maxfitness
{
	for(int i=0;i<zhongqunshu1;i++)//计算shiyingdu
		mubiaohanshu(nowpop[i]);
}
virtual void mubiaohanshu(individual &bianliang)//计算shiyingdu
{
	jishuqi++;
		double he=0;
	for(int i=0;i<jiedeweishu;i++)
	{
		he+=pow(bianliang.geti[i],2)-10*cos(2*PI*bianliang.geti[i])+10;
	}
	bianliang.shiyingdu=-he;
	/*double t=0;
	for(int i=0;i<jiedeweishu-1;i++)
		t+=100*pow(bianliang.geti[i+1]-pow(bianliang.geti[i],2),2)+pow(bianliang.geti[i]-1,2);
	bianliang.shiyingdu=-t;*/
}
void generation()
{
	int j=0,i=0;
	jingzheng();
	//guanjiancanshujisuan();
	//jingyingbaoliu();
	//交叉与变异的实现
	//交叉
	jiaocha();
	//jingyingbaoliu();
	//变异的实现
    for(j=0;j<zhongqunshu1;j++)
	{
		bianyi(nowpop[j]);
	} 
	//精英保留的实现
	jingyingbaoliu();
	//
	//for(j=0;j<zhongqunshu1;j++)
	//{
		//xuexi(nowpop[j]);
	//} 
	xuexi(zuiyougeti);
	

}
void crossover(individual parent1,individual parent2,individual &child1,individual &child2)//交叉
{
int j=0,i=0,jj,yiminpanduan=0;
	if(ran1(a)<PC)//(flipc(parent1.fitness,parent2.fitness))
	{
		double pan1=0;
		do
		{
			for(i=0;i<jiedeweishu;i++)
			{
				pan1=pan1+(parent1.geti[i]-parent2.geti[i]);
			}
			if(pan1==0)
			{
				yiminpanduan=1;
				for(i=0;i<jiedeweishu;i++)
				{
					parent2.geti[i]=parent2.geti[i]+0.2*(exp(-10*gen/maxgen)+0.2)*gasdev(a);//
					if(parent2.geti[i]<zuobianjie[i])
						parent2.geti[i]=zuobianjie[i];
					if(parent2.geti[i]>youbianjie[i])
						parent2.geti[i]=youbianjie[i];
					//while(parent2.geti[i]<zuobianjie[i]||parent2.geti[i]>youbianjie[i]);	
				}
			}
		}while(pan1==0);
		if(yiminpanduan==1)
		{
			yimintongji++;
			mubiaohanshu(parent2);
		}
		j=0,i=0,jj;
		int fenduan[5];
		int inte=0;
		fenduan[0]=0;
		for(i=1;i<4;i++)
		{
			inte=rnd(inte+1,jiedeweishu-(5-(i+1)));
			fenduan[i]=inte;
		}
		fenduan[i]=jiedeweishu;
		/*	for(i=0;i<5;i++)
		{
			cout<<fenduan[i]<<endl;
		}
			system("pause");*/
		individual houdai[houdaishuliang+2];
		vector<double> y(jiedeweishu);
		vector<double> z(jiedeweishu);
		for(i=0;i<jiedeweishu;i++)
		{
			z[i]= min(parent1.geti[i],parent2.geti[i]); 
			y[i]= max(parent1.geti[i],parent2.geti[i]); 
		}
		/*for(i=0;i<jiedeweishu;i++)
		{
			cout<<z[i]<<" ";
		}
		cout<<endl;
			for(i=0;i<jiedeweishu;i++)
		{
			cout<<y[i]<<" ";
		}
		cout<<endl;*/
		//system("pause");
		for(i=0;i<houdaishuliang;i++)
		{
			for(j=0;j<4;j++)
			{
				for(jj=fenduan[j];jj<fenduan[j+1];jj++)
				{
					houdai[i].geti[jj]=z[jj]+(MGA[i][jj]-1)*(y[jj]-z[jj])/(3-1);//
				/*if(houdai[i].geti[j]<zuobianjie[j])
					houdai[i].geti[j]=zuobianjie[j];*/
				/*if(houdai[i].geti[jj]>y[jj])
					houdai[i].geti[jj]=y[jj];*/
				}
			}
		}
		houdai[i]=parent1;
		houdai[i+1]=parent2;
		for(i=0;i<houdaishuliang;i++)
		{
			jiaochatongji++;
			mubiaohanshu(houdai[i]);
		}
		qsort(houdai,(houdaishuliang+2),sizeof(individual),&cmpshiyingdu);
		child1=houdai[0];
		child2=houdai[1];
		//cout<<child1.shiyingdu<<" "<<child2.shiyingdu<<endl;
		//system("pause");
	}
	else
	{
		/*for(jj=0;jj<jiedeweishu;jj++)
		{
			child1.geti[jj]=parent1.geti[jj];
			child2.geti[jj]=parent2.geti[jj];
		}
		child1.shiyingdu=parent1.shiyingdu;
		child2.shiyingdu=parent2.shiyingdu;*/
		child1=parent1;
		child2=parent2;
	}

}
void bianyi(individual &child)//变异
{
	int jj=0;
	for(jj=0;jj<jiedeweishu;jj++)
	{
		if(ran1(a)<0.1)
		{
			double alpha;
			alpha=ran1(a);
			if(alpha>=1/jiedeweishu)
			{
				child.geti[jj]=child.geti[jj]+double(gasdev(a)/sqrt(gen));
			}
			if(child.geti[jj]>youbianjie[jj])
			{
				child.geti[jj]=youbianjie[jj];
			}
			if(child.geti[jj]<zuobianjie[jj])
			{
				child.geti[jj]=zuobianjie[jj];
			}
		}
	}
	mubiaohanshu(child);
}

int rnd(int low, int high)           /*在整数low和high之间产生一个随机整数*/
{
    int i;
    if(low >= high)
        i = low;
    else
    {
        i =(int)((ran1(a) * (high - low + 1)) + low);
        if(i > high) i = high;
    }
    return(i);
}
void jingzheng()
{	
	int i;
	Mm pipei;
	pipei=randperm(zhongqunshu1);
	int x,row,col,linyu[4],maxhao,panduan=0;
	individual fu1,fu2,max;
	for( i=0;i<zhongqunshu1;i++)
	{
		x=pipei.r(i+1);	
		max=nowpop[x-1];
		maxhao=x-1;
		row=floor((x-1)/ac);
		col=(x-1)%(ac);
		if(row==0)
		{
			linyu[0]=ar-1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -