#include <iostream>
#include <math.h>
#include <fstream>
#include <stdlib.h>
#include <windows.h>
using namespace std;
#define MAXPOP 10
#define MAXALL 3
// 52 = a + 2b + 3c
ofstream fout;
void start_pop(), fitness(), probability(), choose_mate(), mutate();
class POPULATION
{
public:
int FitSum;
int ProbSum;
int generation;
}population;
class INDIVIDUAL
{
public:
int fitness;
int probability;
int allele[3];
int mother;
int father;
}individual[MAXPOP];
int main()
{
srand(GetTickCount());
fout.open("stats.txt");
start_pop();
cout << "Simulating Population\n";
while(1)
{
population.FitSum = 0;
population.ProbSum = 0;
population.generation++;
fitness();
probability();
choose_mate();
mutate();
}
return 0;
}
void fitness()
{
int sum = 0;
if(population.generation > 1000)
{
system("pause");
exit(0);
}
for(int i = 0; i < MAXPOP; i++)
{
individual.fitness = 100 - (abs(52 - (individual.allele[0] + (2 * individual.allele[1]) + (3 * individual.allele[2]))));
population.FitSum += individual.fitness;
if(individual.fitness == 100)
{
fout << "+++++++++++++++++++++++++++\n";
fout << "+SOLVED:\n";
fout << "+A = " << individual.allele[0] << endl;
fout << "+B = " << individual.allele[1] << endl;
fout << "+C = " <<individual.allele[2] << endl;
fout << "+Generation: " << population.generation;
fout << "\n+++++++++++++++++++++++++++\n";
cout << "\nSolved\n";
system("pause");
exit(0);
}
}
/*for(int i = 0; i < MAXPOP; i++)
{
if(individual.fitness > (population.FitSum / MAXPOP))
{
individual.fitness += 20;
}
if(individual.fitness < (population.FitSum / MAXPOP))
{
individual.fitness -= 20;
}
} */
return;
}
void probability()
{
for(int i = 0; i < (MAXPOP); ++i)
{
individual.probability = individual.fitness + population.ProbSum;
population.ProbSum += individual.fitness;
}
return;
}
void choose_mate()
{
INDIVIDUAL newpop[MAXPOP];
int pop = 0;
bool fmalleles[3];
while(pop < MAXPOP)
{
fmalleles[rand() % 3] = true;
fmalleles[rand() % 3] = true;
bool father = false;
bool mother = false;
int RandFather = (rand() % population.ProbSum);
int RandMother = (rand() % population.ProbSum);
for(int i = 0; i < (MAXPOP); i++)
{
if(RandFather > individual.probability && RandFather < individual.probability || RandFather == individual<span style="font-weight:bold;">.probability)
{
father = <span class="cpp-keyword">true</span>;
<span class="cpp-keyword">int</span> trans = <span class="cpp-number">0</span>;
<span class="cpp-keyword">while</span>(trans < <span class="cpp-number">3</span>)
{
<span class="cpp-keyword">if</span>(fmalleles[trans] == <span class="cpp-keyword">true</span>)
{
newpop[pop].allele[trans] = individual<span style="font-weight:bold;">.allele[trans];
}
trans++;
}
}
<span class="cpp-keyword">if</span>(RandMother > individual<span style="font-weight:bold;">.probability && RandMother < individual.probability || RandMother == individual<span style="font-weight:bold;">.probability)
{
mother = <span class="cpp-keyword">true</span>;
<span class="cpp-keyword">int</span> trans = <span class="cpp-number">0</span>;
<span class="cpp-keyword">while</span>(trans < <span class="cpp-number">3</span>)
{
<span class="cpp-keyword">if</span>(fmalleles[trans] == <span class="cpp-keyword">false</span>)
{
newpop[pop].allele[trans] = individual<span style="font-weight:bold;">.allele[trans];
}
trans++;
}
}
}
<span class="cpp-keyword">if</span>(mother == <span class="cpp-keyword">false</span> || father == <span class="cpp-keyword">false</span>)
{
pop -= <span class="cpp-number">1</span>;
}
pop++;
}
<span class="cpp-keyword">for</span>(<span class="cpp-keyword">int</span> i = <span class="cpp-number">0</span>; i < (MAXPOP); i++)
{
individual<span style="font-weight:bold;"> = newpop<span style="font-weight:bold;">;
}
<span class="cpp-keyword">return</span>;
}
<span class="cpp-keyword">void</span> start_pop()
{
<span class="cpp-keyword">for</span>(<span class="cpp-keyword">int</span> i = <span class="cpp-number">0</span>; i < (MAXPOP); i++)
{
<span class="cpp-keyword">for</span>(<span class="cpp-keyword">int</span> j = <span class="cpp-number">0</span>; j < <span class="cpp-number">3</span>; j++)
{
individual<span style="font-weight:bold;">.allele[j] = rand() % <span class="cpp-number">10</span> + <span class="cpp-number">1</span>;
}
}
<span class="cpp-keyword">return</span>;
}
<span class="cpp-keyword">void</span> mutate()
{
<span class="cpp-keyword">int</span> pop = <span class="cpp-number">0</span>;
<span class="cpp-keyword">while</span>(pop < MAXPOP)
{
<span class="cpp-keyword">int</span> allele = rand() % <span class="cpp-number">3</span>;
<span class="cpp-keyword">int</span> pm = rand() % <span class="cpp-number">1</span>;
<span class="cpp-keyword">int</span> mutate = rand() % <span class="cpp-number">50</span>;
<span class="cpp-keyword">if</span>(mutate == <span class="cpp-number">15</span> || mutate == <span class="cpp-number">21</span>)
{
<span class="cpp-keyword">if</span>(pm == <span class="cpp-number">0</span>)
{
individual[pop].allele[allele] += <span class="cpp-number">1</span>;
}
<span class="cpp-keyword">else</span>
{
individual[pop].allele[allele] -= <span class="cpp-number">1</span>;
}
}
pop++;
}
<span class="cpp-keyword">return</span>;
}
</pre></div><!–ENDSCRIPT–>
Help with my GA
I've been working on getting this program to work for quite a while. It is supposed to solve the problem "52 = a + 2b + 3c". Please help me to get it to work. It solves the problem sometimes, but other times it just loops the same number until the program ends or it crashes.
I am almost positive it is something wrong with the "Choose_Mate()" function
At first glance:
- You have an off-by-one error regarding MAXPOP (you access newpop[MAXPOP] in the loop when you shouldn't)
- No idea what 'fmalleles' does - is this your crossover operator, effectively? - but it appears that you fail to initialise the array to begin with and then very quickly turn each of the 3 members to true
- "RandFather > individual.probability && RandFather < individual.probability || RandFather == individual<span style="font-weight:bold;">.probability" should probably be "RandFather >= individual<span style="font-weight:bold;">.probability && RandFather < individual.probability"<br><br>Personally I would clean up parts of that function by moving key aspects into other distinct functions: eg. one to perform the selection, another one to perform the cross over, etc.
- You have an off-by-one error regarding MAXPOP (you access newpop[MAXPOP] in the loop when you shouldn't)
- No idea what 'fmalleles' does - is this your crossover operator, effectively? - but it appears that you fail to initialise the array to begin with and then very quickly turn each of the 3 members to true
- "RandFather > individual.probability && RandFather < individual.probability || RandFather == individual<span style="font-weight:bold;">.probability" should probably be "RandFather >= individual<span style="font-weight:bold;">.probability && RandFather < individual.probability"<br><br>Personally I would clean up parts of that function by moving key aspects into other distinct functions: eg. one to perform the selection, another one to perform the cross over, etc.
Thanks ill try that out now.
I do not understand what you mean here
"You have an off-by-one error regarding MAXPOP (you access newpop[MAXPOP] in the loop when you shouldn't"
Even without that part I didn't understand it works, so far as I can tell 100% of the time now. Thank you a lot.
I do not understand what you mean here
"You have an off-by-one error regarding MAXPOP (you access newpop[MAXPOP] in the loop when you shouldn't"
Even without that part I didn't understand it works, so far as I can tell 100% of the time now. Thank you a lot.
individual[MAXPOP] - you have MAXPOP individuals, from 0 to MAXPOP-1.
for(int i = 0; i < (MAXPOP); i++) - That means i can equal MAXPOP-1.
if(RandFather > individual.probability && RandFather < individual - that means you access individual[MAXPOP-1 + 1], which doesn't exist.
for(int i = 0; i < (MAXPOP); i++) - That means i can equal MAXPOP-1.
if(RandFather > individual.probability && RandFather < individual - that means you access individual[MAXPOP-1 + 1], which doesn't exist.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement