-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGeneticAlgorithm.cpp
More file actions
181 lines (153 loc) · 4.65 KB
/
Copy pathGeneticAlgorithm.cpp
File metadata and controls
181 lines (153 loc) · 4.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
// C++ program to create target string, starting from
// random string using a Genetic Algorithm ported from earlier java project
#include <bits/stdc++.h>
using namespace std;
// Number of individuals in each generation
#define POPULATION_SIZE 100
// Valid Genes
const string GENES = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP"\
"QRSTUVWXYZ 1234567890, .-;:_!\"#%&/()=?@${[]}";
// Target string to be generated from the user's input
string TARGET = "";
// Function to generate random numbers in given range
int random_num(int start, int end)
{
int range = (end-start)+1;
int random_int = start+(rand()%range);
return random_int;
}
// Create random genes for mutation
char mutated_genes()
{
int len = GENES.size();
int r = random_num(0, len-1);
return GENES[r];
}
// create chromosome or string of genes
string create_gnome()
{
int len = TARGET.size();
string gnome = "";
for(int i = 0;i<len;i++)
gnome += mutated_genes();
return gnome;
}
// Class representing individual in population
class Individual
{
public:
string chromosome;
int fitness;
Individual(string chromosome);
Individual mate(Individual parent2);
int cal_fitness();
};
Individual::Individual(string chromosome)
{
this->chromosome = chromosome;
fitness = cal_fitness();
};
// Perform mating and produce new offspring
Individual Individual::mate(Individual par2)
{
// chromosome for offspring
string child_chromosome = "";
int len = chromosome.size();
for(int i = 0;i<len;i++)
{
// random probability
float p = random_num(0, 100)/100;
// if prob is less than 0.45, insert gene
// from parent 1
if(p < 0.45)
child_chromosome += chromosome[i];
// if prob is between 0.45 and 0.90, insert
// gene from parent 2
else if(p < 0.90)
child_chromosome += par2.chromosome[i];
// otherwise insert random gene(mutate),
// for maintaining diversity
else
child_chromosome += mutated_genes();
}
// create new Individual(offspring) using
// generated chromosome for offspring
return Individual(child_chromosome);
};
// Calculate fittness score, it is the number of
// characters in string which differ from target
// string.
int Individual::cal_fitness()
{
int len = TARGET.size();
int fitness = 0;
for(int i = 0;i<len;i++)
{
if(chromosome[i] != TARGET[i])
fitness++;
}
return fitness;
};
// Overloading < operator
bool operator<(const Individual &ind1, const Individual &ind2)
{
return ind1.fitness < ind2.fitness;
}
// Driver code
int main()
{
srand((unsigned)(time(0)));
cout << "Enter the target string to be generated: ";
getline(cin, TARGET);
// current generation
int generation = 0;
vector<Individual> population;
bool found = false;
// create initial population
for(int i = 0;i<POPULATION_SIZE;i++)
{
string gnome = create_gnome();
population.push_back(Individual(gnome));
}
while(!found)
{
// sort the population in increasing order of fitness score
sort(population.begin(), population.end());
// if the individual having lowest fitness score ie.
// 0 then we know that we have reached to the target
// and break the loop
if(population[0].fitness <= 0)
{
found = true;
break;
}
// Otherwise generate new offsprings for new generation
vector<Individual> new_generation;
// Perform Elitism, that mean 10% of fittest population
// goes to the next generation
int s = (10*POPULATION_SIZE)/100;
for(int i = 0;i<s;i++)
new_generation.push_back(population[i]);
// From 50% of fittest population, Individuals
// will mate to produce offspring
s = (90*POPULATION_SIZE)/100;
for(int i = 0;i<s;i++)
{
int len = population.size();
int r = random_num(0, 50);
Individual parent1 = population[r];
r = random_num(0, 50);
Individual parent2 = population[r];
Individual offspring = parent1.mate(parent2);
new_generation.push_back(offspring);
}
population = new_generation;
cout<< "Generation: " << generation << "\t";
cout<< "String: "<< population[0].chromosome <<"\t";
cout<< "Fitness: "<< population[0].fitness << "\n";
generation++;
}
cout<< "Generation: " << generation << "\t";
cout<< "String: "<< population[0].chromosome <<"\t";
cout<< "Fitness: "<< population[0].fitness << "\n";
}