gpt4 book ai didi

c++ - C++ 中的遗传算法优化

转载 作者:行者123 更新时间:2023-11-30 01:30:29 27 4
gpt4 key购买 nike

我正在寻找添加或省略代码的有效方法,以帮助我的遗传算法程序更快地返回结果。该程序的目标是接受一个字符串并创建尽可能匹配的其他字符串。无论哪个新制作的字符串与最接近的(前 5 个)匹配并与其他字符串匹配并产生后代(其中一些具有将新随机数放入字符串而不影响长度的突变)。一切正常,但要使一些较长的字符串(4 及以上)完美匹配,需要花费难以估量的几代人。抱歉 tl;dr 长度,但这是我当前的代码。批评走!

    #include "stdio.h"
#include "fstream"
#include "ctime"
#include "iostream"
#include "string"
#include "windows.h"

#define CHARACTERS 16
#define STRINGS 100
/*
Enter String(max 16 chars)
Generate 100 words of the same length
Check for Fitness(how close each word is to the string)
Every generation: display top 5
Clone the top 5
Top 20 reproduce(mix each other's chars)
1/1000 chance the children might mutate(each newly mixed string or char might have a completely random number)

*/

typedef struct _stringHolder
{
char randString[CHARACTERS];
int fitness;
}StringHolder;


//Randomly generate 100 words
void generate(char *myString, StringHolder *SH)
{
unsigned seed = time(0);
srand(seed);
//int i = 0;
int j = 0;
char randChar;
//char showString[CHARACTERS];
for(int i=0; i<STRINGS; i++)
{
for(int j=0; j<strlen(myString); j++)
{
randChar = ('a' + (rand() %26));
SH[i].randString[j] = randChar;
}
//limiter so that it doesn't crash
SH[i].randString[strlen(myString)] = 0;
}
}

//Check the similarity of the random strings to the original string.
void getFitness(char *myString, StringHolder *SH)
{
for(int i=0; i<STRINGS; i++)
{
for(int j=0; j<strlen(myString); j++)
{
if(SH[i].randString[j] == myString[j])
{ SH[i].fitness++; }
}
}
}

//Sort the strings
void sortByFitness(char *myString, StringHolder *SH)
{

bool swapped = 1;
while(swapped)
{
swapped = 0;
for(int a=0; a<STRINGS-1; a++)
{
if(SH[a].fitness < SH[a+1].fitness)
{
swapped = 1;


StringHolder temp[STRINGS];
temp[a] = SH[a+1]/*.randString[i]*/;
SH[a+1]/*.randString[i]*/ = SH[a]/*.randString[i]*/;
SH[a]/*.randString[i]*/ = temp[a];

/*if(SH[a].fitness < SH[a+1].fitness)
{ swapped = 0; }*/
}
}
}//while
}

//Clone the Top 5 strings
void cloneTopFive(char *myString, StringHolder *SH, StringHolder *cloneString)
{
for(int i=0; i<5; i++)
{
cloneString[i]/*.randString[j]*/ = SH[i]/*.randString[j]*/;
//printf("cloneString[%d] now holds %s.\n", i, SH[i].randString);

}
}
//Reproduce the Top 20 strings by mixing and matching elements between strings
void reproduceTopTwenty(char *myString, StringHolder *SH /*char *cloneString*/)
{
/*for(int h=5; h<95; h++)
{*/
for(int i=0; i<20; i++)
{
for(int j=0; j<strlen(myString)-1; j++)
{
//char temp[16];
//temp[i] =
SH[i].randString[j] = SH[1 + (rand() %20)].randString[1 + (rand() %strlen(myString)-1)];
int randomNumber;
randomNumber = (1 +(rand() %100));
if(randomNumber == 7)
{
SH[i].randString[1 + (rand() %strlen(myString)-1)] = ('a' + (rand() %26));
}
}
}

}
//Randomize the other 75 numbers and place the cloned Top 5 at the end of the String Holder(SH)
void randomizeOther75(char *myString, StringHolder *SH, StringHolder *cloneString)
{
for(int i=20; i<STRINGS; i++)
{
for(int j=0; j<strlen(myString); j++)
{
SH[i].randString[j] = ('a' + (rand() %26));
}
}

for(int i=0; i<5; i++)
{
for(int j=0; j<strlen(myString); j++)
{
int v = i + 94;
SH[v].randString[j] = cloneString[i].randString[j];
}
}

}
void printGen(char *myString, StringHolder *SH)
{
for(int i=0; i<5; i++)
{
if(SH[i].fitness == strlen(myString))
{ printf("%s has %d fitness. Perfection!\n", SH[i].randString, SH[i].fitness); }
else
printf("%s has %d fitness.\n", SH[i].randString, SH[i].fitness);
}
}
void main()
{
char myString[CHARACTERS];
StringHolder cloneString[5];
StringHolder SH[STRINGS];
for(int i=0; i<STRINGS; i++)
{ SH[i].fitness = 0; }

printf("Enter your name(no whitespaces): ");
scanf("%s", myString);
/*while(strlen(myString) >= CHARACTERS)
{
printf("Please type a string with less than 16 characters\n");
scanf("%s", myString);
}*/
//printf("%s\n", myString);

//first generation
generate(myString, SH);
int gen = 0;
while(1)
{
char x = ' ';
/* printf("Insert something. Anything!");
scanf(&x);*/


/*char newString[CHARACTERS];
for(int i=0; i<5; i++)
{
for( int j=0; j< strlen(myString); j++)
{
newString[j] = SH[i].randString[j];
}
newString[strlen(myString)] = 0;
printf("%s has %d fitness.\n", newString, SH[i].fitness);
}*/

printf("\n");
while(x==' ')
{
printf("Generation %d: \n", gen);
getFitness(myString, SH);
sortByFitness(myString, SH);

printGen(myString, SH);

for(int i=0; i<STRINGS; i++)
{ SH[i].fitness = 0; }

cloneTopFive(myString, SH, cloneString);
reproduceTopTwenty(myString, SH);
randomizeOther75(myString, SH, cloneString);
/*getFitness(myString, SH);
sortByFitness(myString, SH);

for(int i=0; i<5; i++)
{
printf("%s has %d fitness.\n", SH[i].randString, SH[i].fitness);
}
printf("\n");*/

//printf("\nInsert ' ' to continue!\n");

//scanf("%c",&x);
gen++;
}
}

最佳答案

GA 收敛不佳的一个重要原因是您的适应度函数。忽略程序其他部分的潜在编码错误,您所做的只是奖励完全匹配的字母。健身景观是这样的(害怕我的 ASCII 艺术!):

___________   ___________           | |           |_|a b c d e f G h i j k l m

其中 G 是所需的字母。该算法不知道如何找到 G,而是完全靠运气。您基本上已经实现了随机字母暴力搜索。

使适应度函数奖励“接近”正确的解决方案,收敛速度会更快。还可以调整种群参数、突变、交叉等。

关于c++ - C++ 中的遗传算法优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4424738/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com