遗传算法
最近玩了一下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;
}