Poj1699 遗传算法TSP

题目链接:http://poj.org/problem?id=1699

 

扩展kmp求距离,随机算法求TSP问题。、

 不过强度不给力啊,Age 取1024时跑了250ms,还多以WA结束,下面的跑了刚好1000ms >.<

Code:

 

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#define M 24
#define Swap(x,y,t) {t=x,x=y,y=t;}
const int N = 128;
const int K = 64;
const int KK = 48;
const int Age = 4096;
const int pm = 20;

char s[16][M];
int l[16];
int map[16][16];
int n;
int nxt[M],ext[M];

typedef struct talG{
	int a[16];
	int h;
}Genetic;

Genetic Memory[N];
Genetic *g[N];

typedef int (*CMP)(const void *,const void *);

int Cmp(Genetic **a,Genetic **b)
{
	return (*b)->h-(*a)->h;
}

int ExtendKmp(char s[],int ls,char t[],int lt)
{
	int i,j,k;
	int Len,L;

	j=0;
	while(t[j+1]==t[j]&&j+1<lt) j++;
	nxt[1]=j,k=1;

	for(i=2;i<lt;i++){
		Len=k+nxt[k],L=nxt[i-k];
		if(Len>L+i) nxt[i]=L;
		else{
			j=Len-i>0?Len-i:0;
			while(t[i+j]==t[j]&&i+j<lt) j++;
			nxt[i]=j,k=i;
		}
	}
	j=0;
	while(s[j]==t[j]&&j<lt&&j<ls) j++;
	ext[0]=j,k=0;

	for(i=1;i<ls;i++){
		Len=k+ext[k],L=nxt[i-k];
		if(Len>L+i) ext[i]=L;
		else{
			j=Len-i>0?Len-i:0;
			while(s[i+j]==t[j]&&i+j<ls&&j<lt) j++;
			ext[i]=j,k=i;
		}
	}
	for(i=0;i<ls;i++){
		if(i+ext[i]==ls)
			break;
	}
	return ls-i;
}
int H(int a[])
{
	int i,r=0;
	for(i=1;i<n;i++)
		r+=map[a[i-1]][a[i]];
	return r;
}
void GeneticInit()
{
	int i,j;
	int tmp;
	int a,b;
	for(i=0;i<N;i++){
		g[i]=&Memory[i];
		for(j=0;j<n;j++)
			Memory[i].a[j]=j;
		for(j=n;j;j--){
			a=rand()%n;
			b=rand()%n;
			Swap(g[i]->a[a],g[i]->a[b],tmp);
		}
		g[i]->h=H(g[i]->a);
	}
}
void CrossOver(Genetic *g,Genetic *h)
{
	int a[M],b[M];
	int la,lb;
	int i,tmp;
	int low,up;
	low=rand()%n;
	up=rand()%n;
	for(la=lb=i=0;i<n;i++){
		if(g->a[i]>=low&&g->a[i]<=up)
			a[la++]=i;
		if(h->a[i]>=low&&h->a[i]<=up)
			b[lb++]=i;
	}
	for(i=0;i<la&&i<lb;i++)
		Swap(g->a[a[i]],h->a[b[i]],tmp);
}
void Mutate(Genetic *g)
{
	int tmp;
	int a,b;
	if(rand()%100<pm){
		a=rand()%n;
		b=rand()%n;
		Swap(g->a[a],g->a[b],tmp);
	}
}
int GeneticRun()
{
	//int r;
	int age;
	int i;

	srand(time(NULL));
	GeneticInit();

	for(age=0;age<Age;age++){
		qsort(g,N,sizeof(g[0]),(CMP)Cmp);
		for(i=K;i<N;i+=2){
			*g[i]=*g[rand()%K];
			*g[i+1]=*g[rand()%K];
			CrossOver(g[i],g[i+1]);
		}
		for(i=KK;i<N;i++){
			Mutate(g[i]);
			g[i]->h=H(g[i]->a);
		}
	}
	return g[0]->h;
}

int main()
{
	int t;
	int i,j,tot;

	scanf("%d",&t);

	while(t--){
		scanf("%d",&n);

		for(tot=i=0;i<n;i++){
			scanf("%s",s[i]);
			l[i]=strlen(s[i]);
			tot+=l[i];
		}

		for(i=0;i<n;i++){
			for(j=0;j<n;j++){
				if(i!=j)
					map[i][j]=ExtendKmp(s[i],l[i],s[j],l[j]);
			}
		}
		tot-=GeneticRun();
		printf("%d\n",tot);
	}
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值