遗传算法代码

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

论文地址:

点击打开链接


代码:

#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();
}


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值