【人工智能】遗传算法实验

遗传算法实验

TSP问题

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "math.h"
#include "time.h"
#include <unistd.h>       //提供统一API接口 
#include <bits/stdc++.h>  //万能头文件,包含几乎可以用到的所有C++函数库 
#define Citynum 100     //城市数,编号是0~Citynum-1
#define Popnum 300        //种群个体数
#define Maxbound 10000000 //路径最大值上限
#define N 1000000         //需要根据实际求得的路径值修正
unsigned seed=(unsigned)time(0);
double Hash[Citynum+1];   //哈希表 
typedef struct CityPosition//城市点坐标 
{
    double x;
    double y;
}CityPosition;
CityPosition CityPos[100]={
	//根据城市规模设置相关参数 
    {11003.611100,42102.500000},{11108.611100,42373.888900},{11133.333300,42885.833300},
	{11155.833300,42712.500000},{11183.333300,42933.333300},{11297.500000,42853.333300},
	{11310.277800,42929.444400},{11416.666700,42983.333300},{11423.888900,43000.277800},
	{11438.333300,42057.222200},//10 
	{11461.111100,43252.777800},{11485.555600,43187.222200},{11475.555600,43187.222200},
	{11503.055600,42855.277800},{11511.388900,42106.388900},{11522.222200,42841.944400},
	{11569.444400,43136.666700},{11583.333300,43150.000000},{11595.000000,43148.055600},
	{11600.000000,43150.000000},//20
	{11690.555600,42686.666700},{11715.833300,41836.111100},{11745.277800,42884.444400},
	{11751.111100,42814.444400},{11770.277800,42651.944400},{11785.277800,42884.444400},
	{11822.777800,42673.611100},{11846.944400,42660.555600},{11963.055600,43290.555600},
	{11973.055600,43026.111100},//30 
	{12058.333300,42195.555600},{12149.444400,42477.500000},{13785.177800,42884.444400},
	{12286.944400,43355.555600},{12300.000000,42433.333300},{12355.833300,43156.388900},
	{12363.333300,43189.166700},{12372.777800,42711.388900},{12386.666700,43334.722200},
	{12421.666700,42895.555600},//40
	{13645.000000,42973.333300},{13149.444400,42477.500000},{13785.177800,43884.444400},
	{13286.944400,43355.555600},{13300.000000,42433.333300},{13355.833300,43156.388900},
	{13363.333300,43189.166700},{13372.777800,42711.388900},{13386.666700,43334.722200},
	{14421.666700,42895.555600},//50 
	{14003.611100,44102.500000},{14108.611100,42373.888900},{14133.333300,44885.833300},
	{14155.833300,44712.500000},{14183.333300,42933.333300},{14297.500000,44853.333300},
	{14310.277800,44929.444400},{14416.666700,42983.333300},{14423.888900,45000.277800},
	{14438.333300,44057.222200},//60 
	{11461.111100,45252.777800},{11485.555600,45187.222200},{11475.555600,45187.222200},
	{11503.055600,45855.277800},{11511.388900,45106.388900},{11522.222200,45841.944400},
	{11569.444400,45136.666700},{11583.333300,45150.000000},{11595.000000,45148.055600},
	{11600.000000,45150.000000},//70 
	{11690.555600,46686.666700},{11715.833300,46836.111100},{11745.277800,46884.444400},
	{11751.111100,46814.444400},{11770.277800,46651.944400},{11785.277800,46884.444400},
	{11822.777800,46673.611100},{11846.944400,46660.555600},{11963.055600,46290.555600},
	{11973.055600,46026.111100},//80 
	{12058.333300,47195.555600},{12149.444400,47477.500000},{13785.177800,47884.444400},
	{12286.944400,47355.555600},{12300.000000,47433.333300},{12355.833300,47156.388900},
	{12363.333300,47189.166700},{12372.777800,47711.388900},{12386.666700,47334.722200},
	{12421.666700,47895.555600},//90 
	{13645.000000,48973.333300},{13149.444400,48477.500000},{13785.177800,48884.444400},
	{13286.944400,48355.555600},{13300.000000,48433.333300},{13355.833300,48156.388900},
	{13363.333300,48189.166700},{13372.777800,48711.388900},{13386.666700,48334.722200},
	{14421.666700,48895.555600}//100
};
double CityDistance[Citynum][Citynum];//城市距离词典
typedef struct{
    int colony[Popnum][Citynum+1];//城市种群,默认出发城市编号为0,则城市编号的最后一个城市还应该为0
    double fitness[Popnum];//每个个体的适应值,即1/Distance[Popnum]
    double Distance[Popnum];//每个个体的总路径
    int BestRooting[Citynum+1];//最优城市路径序列
    double BestFitness;//最优路径适应值
    double WorstFitness;//最差路径适应值
    double SumFitness;//适应度之和 
    double priFitness;//平均适应度 
    double BestValue;//最优路径长度
    int BestNum;
}TSP,*PTSP;

/*计算城市距离词典CityDistance[i][j]*/
void CalculatDist(){
    int i,j;
    double temp1,temp2;
    for(i=0;i<Citynum;i++){
        for(j=0;j<=Citynum;j++){//最后一个城市还应该返回到出发节点
            temp1=CityPos[j].x-CityPos[i].x;
            temp2=CityPos[j].y-CityPos[i].y;
            CityDistance[i][j]=sqrt(temp1*temp1+temp2*temp2);
        }
    }
}
/*数组复制*/
void copy(int a[],int b[]){
    int i=0;
    for(i=0;i<Citynum+1;i++){
        a[i]=b[i];
    }
}
/*用来检查新生成的节点是否在当前群体中*/
//0号节点是默认出发节点和终止节点
bool check(TSP &city,int pop,int num,int k){
    int i;
    for(i=0;i<=num;i++){
        if(k==city.colony[pop][i])
            return true;//新生成节点存在于已经生成的路径中
    }
    return false;//新生成节点没有存在于已经生成的路径中
}
/*种群初始化,即为city.colony[i][j]赋值*/
void InitColony(TSP &city){
    int i,j,r;
    for(i=0;i<Popnum;i++){
        city.colony[i][0]=0;//默认出发城市为0 
        city.colony[i][Citynum]=0;//城市编号的最后一个城市也为0 
        city.BestValue=Maxbound;
        city.BestFitness=0;//适应值越大越好
        city.WorstFitness=100;
        city.SumFitness=0;
		city.priFitness=0; 
    }
    for(i=0;i<Popnum;i++){
        for(j=1;j<Citynum;j++){
            r=rand()%(Citynum-1)+1;//产生1~Citynum-1之间的随机数
            while(check(city,i,j,r))//随机产生城市序号,即为city.colony[i][j]赋值
            { r=rand()%(Citynum-1)+1;}
            city.colony[i][j]=r;
        }
    }
}
/*计算适应值,考虑应该在这里面把最优选出来*/ 
void CalFitness(TSP &city)
{
    int i,j;
    int start,end;
    int Best=0,Worst=0;
    city.SumFitness=0;
    for(i=0;i<Popnum;i++){//求每个个体的总路径,适应值
        city.Distance[i]=0;
        for(j=1;j<=Citynum;j++){
            start=city.colony[i][j-1];//与此城市相邻的上一个城市 
			end=city.colony[i][j];//此城市 
            city.Distance[i]=city.Distance[i]+CityDistance[start][end];//city.Distance[i]每个个体的总路径
        }
        city.fitness[i]=N/city.Distance[i];
        if(city.fitness[i]>city.fitness[Best])//选出最大的适应值,即选出所有个体中的最短路径
            Best=i;
        if(city.fitness[i]<city.fitness[Worst])//选出最小的适应值
            Worst=i;
        city.SumFitness=city.SumFitness+city.fitness[i];//总适应值就是将所有的适应值相加 
    }
    copy(city.BestRooting,city.colony[Best]);//将最优个体拷贝给city.BestRooting
    city.BestFitness=city.fitness[Best];
    city.WorstFitness=city.fitness[Worst];
    city.BestValue=city.Distance[Best];
    city.priFitness=city.SumFitness/Popnum;//计算平均适应度 
    city.BestNum=Best;
}
/*选择算子:轮盘赌法*/ 
void Select(TSP &city)
{
    int TempColony[Popnum][Citynum+1];
    int i,j,t;
    double s;
    double GaiLv[Popnum];
    double SelectP[Popnum+1];
    double avg;
    double sum=0;
    for(i=0;i<Popnum;i++)
    {sum+=city.fitness[i];}//算出总适应度 
    for(i=0;i<Popnum;i++)
    {GaiLv[i]=city.fitness[i]/sum;}//被选中的比例 
    SelectP[0]=0;
    for(i=0;i<Popnum;i++)
    {SelectP[i+1]=SelectP[i]+GaiLv[i]*RAND_MAX;}//选中的概率 
    memcpy(TempColony[0],city.colony[city.BestNum],sizeof(TempColony[0]));//memcpy函数用于把资源内存(src所指向的内存区域) 拷贝到目标内存(dest所指向的内存区域)
	for(t=1;t<Popnum;t++){
        double ran = rand() % RAND_MAX + 1;
        s= (double) ran / 100.0;
        for(i=1;i<Popnum;i++){
            if(SelectP[i]>=s)
                break;
        }
        memcpy(TempColony[t],city.colony[i-1],sizeof(TempColony[t]));
    }
    for(i=0;i<Popnum;i++){
        memcpy(city.colony[i],TempColony[i],sizeof(TempColony[i]));
    }
}
/*交叉:头尾不变,中间打乱顺序交叉*/
//交叉概率是pc
void Cross(TSP &city,double pc)
{
    int i,j,t,l;
    int a,b,ca,cb;
    int Temp1[Citynum+1],Temp2[Citynum+1];
    for(i=0;i<Popnum;i++){
        double s=((double)(rand()%RAND_MAX))/RAND_MAX;
        if(s<pc){
            cb=rand()%Popnum;
            ca=cb;
            if(ca==city.BestNum||cb==city.BestNum)//如果遇到最优则直接进行下次循环
                continue;
            l=rand()%50+1;//n/2
            a=rand()%(Citynum-l)+1;//1-37
            memset(Hash,0,sizeof(Hash));//作用是将某一块内存中的内容全部设置为指定的值,这个函数通常为新申请的内存做初始化工作。
            Temp1[0]=Temp1[Citynum]=0;
            for(j=1;j<=l;j++)//打乱顺序即随机,选出来的通过Hash标记为1
            {
                Temp1[j]=city.colony[cb][a+j-1]; //a+L=2~38 20~38
                Hash[Temp1[j]]=1;
            }
            for(t=1;t<Citynum;t++)
            {
                if(Hash[city.colony[ca][t]]==0)
                {
                    Temp1[j++]=city.colony[ca][t];
                    Hash[city.colony[ca][t]]=1;
                }
            }
            memcpy(city.colony[ca],Temp1,sizeof(Temp1));
        }
    }

}
/*变异*/
double GetFittness(int a[Citynum+1])
{
    int i,start,end;
    double Distance=0;
    for(i=0;i<Citynum;i++)
    {
        start=a[i];   end=a[i+1];
        Distance+=CityDistance[start][end];
    }
    return N/Distance;
}
/*对换变异*/
//变异概率是pm
void Mutation(TSP &city,double pm)
{
    int i,k,m;
    int Temp[Citynum+1];
    for(k=0;k<Popnum;k++)
    {
        double s=((double)(rand()%RAND_MAX))/RAND_MAX;//随机产生概率0~1间
        i=rand()%Popnum;//随机产生0~Popnum之间的数
        if(s<pm&&i!=city.BestNum)//i!=city.BestNum,即保证最优的个体不变异
        {
            int a,b,t;
            a=(rand()%(Citynum-1))+1;
            b=(rand()%(Citynum-1))+1;
            copy(Temp,city.colony[i]);
            if(a>b)//保证让b>=a
            {
                t=a;
                a=b;
                b=t;
            }
            for(m=a;m<(a+b)/2;m++)
            {
                t=Temp[m];
                Temp[m]=Temp[a+b-m];
                Temp[a+b-m]=t;
            }

            if(GetFittness(Temp)<GetFittness(city.colony[i]))
            {
                a=(rand()%(Citynum-1))+1;
                b=(rand()%(Citynum-1))+1;
                memcpy(Temp,city.colony[i],sizeof(Temp));
                if(a>b)
                {
                    t=a;
                    a=b;
                    b=t;
                }
                for(m=a;m<(a+b)/2;m++)
                {
                    t=Temp[m];
                    Temp[m]=Temp[a+b-m];
                    Temp[a+b-m]=t;
                }

                if(GetFittness(Temp)<GetFittness(city.colony[i]))
                {
                    a=(rand()%(Citynum-1))+1;
                    b=(rand()%(Citynum-1))+1;
                    memcpy(Temp,city.colony[i],sizeof(Temp));
                    if(a>b)
                    {
                        t=a;
                        a=b;
                        b=t;
                    }
                    for(m=a;m<(a+b)/2;m++)
                    {
                        t=Temp[m];
                        Temp[m]=Temp[a+b-m];
                        Temp[a+b-m]=t;
                    }
                }

            }
            memcpy(city.colony[i],Temp,sizeof(Temp));
        }
    }
}
void OutPut(TSP &city)
{
    int i,j;
    printf("最佳路径为:\n");
    for(i=0;i<=Citynum;i++){ 
    	if(i==Citynum) 
    	printf("%d",city.BestRooting[i]);
    	else
    	printf("%d-->",city.BestRooting[i]);
	} 
    printf("\n最佳路径值为:%f\n",(city.BestValue));
}
int main()
{
    TSP city;
    double pcross,pmutation;//交叉概率和变异概率
    double Sfitness=0;//适应度之和
	double Pfitness;//平均适应度 
    int MaxEpoc;//最大迭代次数
    int i;
    srand(seed);
    MaxEpoc=30000;
    pcross=0.85; pmutation=0.15;
    CalculatDist();//计算城市距离词典
    InitColony(city);//生成初始种群
    CalFitness(city);//计算适应值,考虑应该在这里面把最优选出来
	int begintime,endtime;//计算时间 
	double Ptime;
	begintime=clock();
    for(i=0;i<MaxEpoc;i++)
    {
	    Select(city);//选择(复制):轮盘赌法
        Cross(city,pcross);//交叉
        Mutation(city,pmutation);//变异
        CalFitness(city);//计算适应值
        Sfitness=Sfitness+city.priFitness; 
    }
    endtime=clock();
    Ptime=float(endtime-begintime)/MaxEpoc;
    Pfitness=Sfitness/MaxEpoc;
	printf("最大适应度:%lf\n",city.BestFitness); 
	printf("最小适应度:%lf\n",city.WorstFitness); 
	printf("平均适应度:%lf\n",Pfitness); 
	printf("平均时间:%lfms\n",Ptime);
    OutPut(city);//输出
    return 0;
}

rosenbrock问题

#include <iostream>
#include "time.h"
#include "stdlib.h"
#include <cmath>
using namespace std;

const int M=8,T=3;//M种群大小,T终止代数
const double pc=0.6,pm=0.01;//pc交叉概率,pm变异概率


struct population      //定义群体结构
{
	int x[20];
	double x1,x2;
	double fit;
	double sumfit;
}p[M];


void initial(population *);//初始化函数
void evaluefitness(population *);//计算适应度
void select(population *);//选择复制函数
void crossover(population *);//交叉函数
void mutation(population *);//变异参数
void decoding(population *);//解码函数
void print(population *);//显示函数


int main()//遗传算法主函数
{
	int gen=0;
	initial(&p[0]);//随机获得初始解
	cout<<"initialed!"<<endl;
	print(&p[0]);
	decoding(&p[0]);//先解码
	cout<<"decoded!"<<endl;
	print(&p[0]);
	evaluefitness(&p[0]);//计算适应度值与累计适值
	cout<<"evalued!"<<endl;
	print(&p[0]);
	while(gen<=T)
	{
		cout<<"gen="<<gen+1<<endl;
		select(&p[0]);//执行选择操作
		decoding(&p[0]);
		evaluefitness(&p[0]);
		cout<<"selected!"<<endl;
		print(&p[0]);
		crossover(&p[0]);//执行交叉操作
		decoding(&p[0]);
		evaluefitness(&p[0]);
		cout<<"crossovered!"<<endl;
		print(&p[0]);
		mutation(&p[0]);//执行变异操作
		decoding(&p[0]);
		evaluefitness(&p[0]);
		cout<<"mutated!"<<endl;
		print(&p[0]);
		gen++;
	}
	decoding(&p[0]);
	evaluefitness(&p[0]);
	cout<<"最后得出的满意解为:"<<endl;
	for(int i=0;i<M;i++)
		cout<<"x1:"<<p[i].x1<<"  x2:"<<p[i].x2<<"  值:"<<p[i].fit<<endl;
	return 0;
}



///初始化函数//
int rand01()//用于随机取0或1的函数
{
	int r;
	double q;
	q=rand()/(RAND_MAX+0.0);
	if(q<0.5)
		r=0;
	else
		r=1;
	return r;
}

void initial(population *t)//群体初始化函数
{
	int j;
	population *po;
	srand(time(0));
	for(po=t;po<t+M;po++)//产生组成的种群个体数为M个的个体 
		for(j=0;j<40;j++)
			(*po).x[j]=rand01();//产生20位字符串表示为个体 
}


/计算适应值函数
void evaluefitness(population *t)//计算适应值函数
{
	double f,x1,x2,x3,x4,temp=0.0;
	population *po,*po2;
	for(po=t;po<t+M;po++)
	{

        x1=po->x1;
        x2=po->x2;
		f=100.0*(x1*x1-x2*x2)*(x1*x1-x2*x2)+(1.0-x1)*(1.0-x1)
		(*po).fit=f;
	}
	for(po=t;po<t+M;po++)//计算累计适应值
	{
		for(po2=t;po2<=po;po2++)
			temp=temp+(*po2).fit;
		(*po).sumfit=temp;
		temp=0.0;
	}
}


/复制函数/
double randab(double a ,double b)//在区间(a,b)内产生一个随机数
{
	double c,r;
	c=b-a;
	r=a+c*rand()/(RAND_MAX+1.0);
	return r;
}


void select(population *t)//选择算子函数
{
	int i=0;
	population pt[M],*po;
	double s;
	srand(time(0));
	while(i<M)
	{
		s=randab((*t).sumfit,(*(t+M-1)).sumfit);//产生一个随机数 
		for(po=t;po<t+M;po++)
		{
			if((*po).sumfit>=s)//如果总适应度大于等于这个随机数,则进行复制 
			{
				pt[i]=(*po);
				break;
			}
			else
				continue;
		}
		i++;
	}
	for(i=0;i<M;i++)//将复制后数据pt[M]转入p[M]
		for(int j=0;j<20;j++)
			p[i].x[j]=pt[i].x[j];
}


/交叉函数/
void crossover(population *t)//交叉算子算法
{
	population *po;
	double q;//用于存放一个0到1的随机数
	int d,e,tem[20];//d存放从1到19的一个随机位置,用来确定交叉的位置
	                //e存放一个0到M的随机且与当前p[i]中i不同的整数,用来确定交叉的对象
	srand(time(0));
	for(po=t;po<t+M;po++)
	{
		q=rand()/(RAND_MAX+0.0);//产生一个随机数 
		if(q<pc)
		{
			for(int j=0;j<M;j++)//运算M次,避免产生群体中某个体与自己交叉的情况
			{
				e=rand()%M;//随机确定交叉对象
				if(t+e!=po)//不能重复
					break;
			}
			d=1+rand()%19;//随机确定交叉位置
			for(int i=d;i<20;i++)//进行交叉 
			{
				tem[i]=(*po).x[i];
				(*po).x[i]=(*(t+e)).x[i];
				(*(t+e)).x[i]=tem[i];
			}
		}
		else
			continue;
	}
}


/变异函数//
void mutation(population *t)//变异算子函数
{
	double q;//q用来存放针对每个基因产生的[0,1]的随机数
	population *po;
	srand(time(0));
	for(po=t;po<t+M;po++)
	{
		int i=0;
		while(i<20)
		{
			q=rand()/(RAND_MAX+0.0);
			if(q<pm)
				(*po).x[i]=1-(*po).x[i];
			i++;
		}
	}
}


解码函数
int dexp(int a,int n)
{
	int m=1;
	for(int i=0;i<n;i++)
		m=m*2;
	m=m*a;
	return m;
}
void decoding(population *t)//解码函数
{
	population *po;
	int temp,s1=0,s2=0,s3=0,s4=0;
	double m,n,dit;
	n=dexp(1,10);//n=2^10
//	dit=4.096/n; 
    dit=60/n;
	for(po=t;po<t+M;po++)
	{
		for(int i=0;i<10;i++)
		{
			temp=dexp((*po).x[i],i);
			s1=s1+temp;
		}
//		m=-2.048+s1*dit;
        m=-30.00+s1*dit; 
		(*po).x1=m;
		s1=0;
		
		for(int j=10;j<20;j++)
		{
			temp=dexp((*po).x[j],j-10);
			s2=s2+temp;
		}
//		m=-2.048+s2*dit;
        m=-30.00+s2*dit;
		(*po).x2=m;
		s2=0;	
	}
}


/显示函数///
void print(population *t)//显示函数
{
	population *po;
	for(po=t;po<t+M;po++)
	{
		for(int j=0;j<20;j++)
		{
//			cout<<(*po).x[j];
            cout<<po->x[j];
			if((j+1)%5==0)
				cout<<" ";
		}
		cout<<endl;
		cout<</*(*po).x1*/po->x1<<" "<</*(*po).x2*/po->x2<</*(*po).fit*/po->fit<<" "<</*(*po).sumfit*/po->sumfit<<endl;
	}
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值