扩大
缩小

遗传算法

最近玩了一下boxcar2d,学习了下遗传算法,大佬都是写的三角形bmp遗传,我只会写点简单的

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<ctime>

using namespace std;

const int MaxnPopu=10001;
const int MaxnStringLen=101;
int PerNum=10;
int MaxnNum=100;

string target;
string NowPopu[MaxnPopu];

int Dif[MaxnPopu];

struct StringInfor{
	int Dif;
	string s;
	bool operator < (const StringInfor &b) const {
		return Dif<b.Dif;
	}
}SI[MaxnPopu];

char RandChar(){
	int opt=rand()%3;
	if(opt==0){
		return 'A'+(rand()%26);
	}else if(opt==1){
		return 'a'+(rand()%26);
	}else if(opt==2){
		return '0'+(rand()%10);
	}
}

int TurnChar(char a){
	if('A'<=a and a<='Z'){
		return a-'A'+1;
	}else if('a'<=a and a<='z'){
		return a-'a'+43;
	}else if('0'<=a and a<='9'){
		return a-'0'+105;
	}
}

char Varia(char a){
	if('A'<=a and a<='Z'){
		int ret=rand()%3+1;
		if('A'>a+ret or a+ret>'Z') return a-ret;
		if('A'>a-ret or a-ret>'Z') return a+ret;
		if(rand()%2){
			return a-ret;
		}else return a+ret;
	}else if('a'<=a and a<='z'){
		int ret=rand()%3+1;
		if('a'>a+ret or a+ret>'z') return a-ret;
		if('a'>a-ret or a-ret>'z') return a+ret;
		if(rand()%2){
			return a-ret;
		}else return a+ret;
	}else if('0'<=a and a<='9'){
		int ret=rand()%3+1;
		if('0'>a+ret or a+ret>'9') return a-ret;
		if('0'>a-ret or a-ret>'9') return a+ret;
		if(rand()%2){
			return a-ret;
		}else return a+ret;
	}
}

string RandString(){
	int len=rand()%MaxnStringLen;
	string ret;char ss[MaxnStringLen];
	memset(ss,0,sizeof(ss));
	for(int i=0;i<len;i++){
		ss[i]=RandChar();
	}
	ret=ss;
	return ret;
}

void Init(){
	for(int i=1;i<=MaxnNum;i++){
		NowPopu[i]=RandString();
	}
}

int Dis(char a,char b){
	return abs(TurnChar(a)-TurnChar(b));
}

int GetDif(string s1,string s2){
	int ret=0;
	ret+=(s1.size()-s2.size())*(s1.size()-s2.size())*1000;
	for(int i=0;i<max(s1.size(),s2.size());i++){
		if(i<s2.size() and i<s1.size())ret+=Dis(s1[i],s2[i]);
		else ret+=100;
	}
	return ret;
}

string Cross(string fa,string ma,int Sum1,int Sum2){
	int len1=fa.size(),len2=ma.size();
	int len=rand()%(max(len1,len2)+10)+1;
	string ret;char ss[101];
	memset(ss,0,sizeof(ss));
	for(int i=0;i<len;i++){
		if(rand()%1000<50){
			if(i>=len1){
				ss[i]=Varia(ma[i]);
				continue;
			} else if(i>=len2){
				ss[i]=Varia(fa[i]);
				continue;	
			} else {
				char tmp;
				if(i>=target.size())tmp='A';
				else tmp=target[i];
				int ch1=Dis(fa[i],tmp);
				int ch2=Dis(ma[i],tmp);
				ss[i]=Varia(ch1<ch2?fa[i]:ma[i]);
			}
		} else {
			if(i>=len1){
				ss[i]=ma[i];
				continue;
			} else if(i>=len2){
				ss[i]=fa[i];
				continue;	
			} else {
				char tmp;
				if(i>=target.size())tmp='A';
				else tmp=target[i];
				double ch1=Dis(fa[i],tmp);
				double ch2=Dis(ma[i],tmp);
				ss[i]=ch1<ch2?fa[i]:ma[i];
			} 
		}
	}
	ret=ss;
	return ret;
}

void Solve(){
	int MiniDif;
	int Geration=0;
	do{
		Geration++;
		MiniDif=0x7fffffff;
		cout<<"Now Geration is : "<<Geration<<endl;
		for(int i=1;i<=MaxnNum;i++){
			cout<<NowPopu[i]<<endl;
		}
		for(int i=1;i<=MaxnNum;i++){
			Dif[i]=GetDif(NowPopu[i],target);
			MiniDif=min(MiniDif,Dif[i]);
			SI[i]=(StringInfor){Dif[i],NowPopu[i]};
		}
		sort(SI+1,SI+MaxnNum+1);
		int Num=0;
		for(int i=1;i<=PerNum;i++){
			for(int j=i+1;j<=PerNum;j++){
				NowPopu[++Num]=Cross(SI[i].s,SI[j].s,SI[i].Dif,SI[j].Dif);
			}
		}
		for(int i=1;i<=5;i++){
			NowPopu[++Num]=SI[i].s;
		}
		for(int i=Num+1;i<=MaxnNum;i++){
			int opt1=rand()%MaxnNum+1;
			int opt2=rand()%MaxnNum+1;
			NowPopu[i]=Cross(SI[opt1].s,SI[opt2].s,SI[opt1].Dif,SI[opt2].Dif);
		}
		puts("------------------------------------------");
	}while(MiniDif);
	printf("Final Geration:%d",Geration); 
}
int main(){
	srand(time(NULL));
	cin>>target;
	cin>>MaxnNum;
	PerNum=MaxnNum*0.2;
	Init();
	system("pause");
	Solve();
	return 0;
}
posted @ 2019-02-23 16:37  ezoiHY  阅读(220)  评论(0编辑  收藏  举报