遗传算法代码

基于论文《最大团问题改进的遗传算法》

论文地址:

点击打开链接


代码:

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
//#define DEBUG

const int max_size = 1600;//数据容量上限
const int N = 10;//搜索数据
const int M = N / 2;
const double alpha = 0.001;
const int delta = 3;
const double lamda = 0.1;
const int cirle = 10000;
const double beta = 0.9;
int bound;
int t = 0;//演化代数
int edges[max_size][max_size];//邻接矩阵
const int size = 1534;//实际数据大小,需要自己设定
int U[max_size];
int Us[N][max_size];
double P[N];
int better[M];

void initial_P();
void update_P();
void local_search(int U[]);
void create_U();
bool judge_allsame();
void select_better(int length);
void change();
void lets_run();


//在迭代之前初始化P
void initial_P()
{
	for(int i = 0;i<N;i++)
	{
		int sum = 0;
		for(int j = 0;j<N;j++)
			sum += Us[j][i];
		P[i] = (double)sum / N;
	}
}
void update_P()
{
	for(int i = 0;i<N;i++)
	{
		int sum = 0;
		for(int j = 0;j<M;j++)
			sum += Us[better[j]][i];
		P[i] = P[i] * (1 - lamda) + lamda * (double)sum / M;
	}
}
void local_search(int U[])
{
	//步骤一
	int  W [max_size];
	int  S [max_size];//记录的是W中标号为1的下标值
	//将数据进行压缩
	int len = 0;//实际数据长度
	for(int i = 0;i<size;i++){
		
		W[i] = U[i];
	
		if(U[i] == 1)
			len++;
	}
	
	while(len > 0)
	{
		int dex;
		int chose;
		//随机从W中选取一个顶点chose
		int num = 0;
		for(int i = 0;i<size;i++)
			if(W[i])
				S[num++] = i;
		chose = S[rand()%num];
		
		len--;
		//以alpha的概率将dex从S中去除
		double alpha_rand = (rand()%100001)/100000.0;
		if(alpha_rand < alpha)
			U[chose] = 0;
		else{
			for(int i = 0;i<size;i++)
			{
				if(i != chose && U[i] == 1 && edges[chose][i] == 0){
					U[i] = 0;
					W[i] = 0;
				}
			}
		}
	}
	//步骤二
	len = 0;
	for(int i = 0;i<size;i++)
	{
		W[i] = (U[i] )? 0:1;
		if(!U[i])
			len++;
	}
	while(len > 0)
	{
		int dex;
		int chose;
		int num = 0;
		for(int i = 0;i<size;i++)
			if(W[i])
				S[num++] = i;
		chose = S[rand()%num];
		W[chose] = 0;
		
		len--;
		int plag = 0;
		for(int i = 0;i<size;i++)
		{
			if(i != chose && U[i] == 1 && edges[chose][i] == 0){
				plag = 1;
				break;
			}
		}
		if(!plag)
			U[chose] = 1;
	}
}

void create_U()
{
	if(t == 0){
		for(int i = 0;i<size;i++)
			U[i] = rand()%2;
		
	}

	else
	{
		//初始化US
		for(int i = 0;i<N;i++)
		{
			for(int j = 0;j<size;j++)
				Us[i][j] = 0;
		}
		
		for(int i = 0;i<N;i++)
		{
			int type = (rand()%delta+1) + bound;
			
			while(1)
			{
				int dex = rand() % size;
				
				if(Us[i][dex] == 0){
					Us[i][dex] = 1;
					type--;
					if(type == 0)
						break;
				}
			}
		}
		
	}
}

bool judge_allsame()
{
	for(int i = 0;i<size;i++)
	{
		int num = Us[0][i];
		for(int j = 1;j<N;j++)
			if(num != Us[j][i])
				return 0;
	}
	return 1;
}

void select_better(int length)
{
	int fx[N];
	for(int i = 0;i<N;i++)
	{
		int sum = 0;
		for(int j = 0;j<size;j++)
			if(Us[i][j] == 1)
				sum++;
		fx[i] = sum;
	}
	for(int i = 0;i<length;i++)
	{
		int max = i;
		int j;
		for(j = i+1;j<N;j++)
			if(fx[max] < fx[j])
				max = j;
		if(max != j)
		{
			int m = fx[max];
			fx[max] = fx[j];
			fx[j] = m;
			better[i] = max;
		}
	}

}
void change()
{
	int U_part[M][max_size];
	for(int i = 0;i<M;i++)
	{
		for(int j = 0;j<size;j++)
		{
			//判断是否进行变异
			double pri = (rand()%100001)/100000.0;
			if(pri < beta)
			{
				pri = (rand()%100001)/100000.0;
				if(pri < P[j])
					U_part[i][j] = 1;
				else
					U_part[i][j] = 0;
			}
			else
				U_part[i][j] = Us[better[0]][j];
		}
	}
	//进行求极大团
	for(int i = 0;i<M;i++)
	{
		local_search(U_part[i]);
	}
	//将种群进行归并
	int dex = 0;
	for(int i = 0;i<M;i++)
	{
		if(dex != better[i]){
			for(int j = 0;j<size;j++)
				Us[dex][j] = Us[better[i]][j];
		}
		dex++;
	}
	for(int i = M;i<N;i++)
	{
		for(int j = 0;j<size;j++)
			Us[i][j] = U_part[i-M][j];
	}
}

void lets_run()
{
	bound = 0;
	int plag = 0;
	while(true)
	{
		//初始化
		if(t == 0){
			create_U();
			local_search(U);
			for(int i = 0;i<size;i++){
				if(U[i] == 1)
					bound++;
			}
			t++;
		}
		
		//随机产生N个编码
		if(plag == 1 || plag == 0){
			create_U();
			
			//对N个编码进行校正,生成N个极大团
			for(int i = 0;i<N;i++)
				local_search(Us[i]);
		}
		//初始化变异率向量
		initial_P();
		
		//选择N/2个较优的个体构成父体
		if(plag == 2)
		select_better(M);
		
		//对选择出的N/2个父体,更新P
		update_P();
		
		//对t代的父体中最优的个体进行M次变异操作,再进行局部搜索并和之前
		//的父体进行合并
		change();
		
		t++;
		//选择最优的个体,并进行输出
		select_better(1);
		
		int bound1 = 0;
		for(int i = 0;i<size;i++)
			if(Us[better[0]][i] == 1)
				bound1++;
		if (t > cirle)
		{
			printf("Result:t:%d     bound:%d\n",t,(bound > bound1)?bound:bound1);
			break;
		}
		if(bound1 > bound)
		{
			plag = 1;
			bound = bound1;
			printf("t:%d     bound:%d\n", t,bound);
			continue;
		}
	  	printf("t:%d     bound:%d\n", t,bound);
		
		if(judge_allsame)
			plag = 1;
		else
			plag = 2;
		
	}
}


int main()
{
	srand((unsigned)time(NULL));
	FILE *in = fopen("E:/stest/test_26.txt","r");
	char char1,char2,*c;
	int size1,len_num,dex_i,dex_j;
	fscanf(in,"%d%d",&size1,&len_num);
#ifdef DEBUG
	printf("len_edge:%d;len_num:%d\n",size1,len_num);
#endif
	for(int i = 0;i<size;i++){
		for(int j = 0;j<size;j++)
		{
			edges[i][j] = 0;
		}
	}	
	for(int i = 0;i<len_num;i++){
		fscanf(in,"%s%d%d",&c, &dex_i, &dex_j);
		
		#ifdef DEBUG
			printf("%c %d  %d\n",c,dex_i,dex_j);
		#endif
		edges[dex_i-1][dex_j-1] = 1;
		edges[dex_j-1][dex_i-1] = 1;
	}
	lets_run();
}


简单的遗传算法,计算函数最值. function ga_main() % 遗传算法程序 % n-- 种群规模% ger-- 迭代次数% pc--- 交叉概率% pm-- 变异概率 % v-- 初始种群(规模为n)% f-- 目标函数值% fit-- 适应度向量 % vx-- 最优适应度值向量% vmfit-- 平均适应度值向量 clear all; close all; clc;%清屏 tic;%计时器开始计时 n=20;ger=100;pc=0.65;pm=0.05;%初始化参数 %以上为经验值,可以更改。 % 生成初始种群 v=init_population(n,22); %得到初始种群,22串长,生成20*22的0-1矩阵 [N,L]=size(v); %得到初始规模行,列 disp(sprintf('Number of generations:%d',ger)); disp(sprintf('Population size:%d',N)); disp(sprintf('Crossover probability:%.3f',pc)); disp(sprintf('Mutation probability:%.3f',pm)); %sprintf可以控制输出格式 % 待优化问题 xmin=0;xmax=9; %变量X范围 f='x+10*sin(x.*5)+7*cos(x.*4)'; % 计算适应度,并画出初始种群图形 x=decode(v(:,1:22),xmin,xmax);"位二进制换成十进制,%冒号表示对所有行进行操作。 fit=eval(f);%eval转化成数值型的 %计算适应度 figure(1);%打开第一个窗口 fplot(f,[xmin,xmax]);%隐函数画图 grid on;hold on; plot(x,fit,'k*');%作图,画初始种群的适应度图像 title('(a)染色体的初始位置');%标题 xlabel('x');ylabel('f(x)');%标记轴 % 迭代前的初始化 vmfit=[];%平均适应度 vx=[]; %最优适应度 it=1; % 迭代计数器 % 开始进化 while it<=ger %迭代次数 0代 %Reproduction(Bi-classist Selection) vtemp=roulette(v,fit);%复制算子 %Crossover v=crossover(vtemp,pc);%交叉算子 %Mutation变异算子 M=rand(N,L)<=pm;%这里的作用找到比0.05小的分量 %M(1,:)=zeros(1,L); v=v-2.*(v.*M)+M;%两个0-1矩阵相乘后M是1的地方V就不变,再乘以2. NICE!!确实好!!!把M中为1的位置上的地方的值变反 %这里是点乘 %变异 %Results x=decode(v(:,1:22),xmin,xmax);%解码,求目标函数值 fit=eval(f); %计算数值 [sol,indb]=max(fit);% 每次迭代中最优目标函数值,包括位置 v(1,:)=v(indb,:); %用最大值代替 fit_mean=mean(fit); % 每次迭代中目标函数值的平均值。mean求均值 vx=[vx sol]; %最优适应度值 vmfit=[vmfit fit_mean];%适应度均值 it=it+1; %迭代次数计数器增加 end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值