Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

The last commit, class is over

  • Loading branch information...
commit 80075eca2888d6add7cb19d9624611edaa8b14b9 1 parent f2a5780
robotapocalypse authored
View
BIN  ga/ga
Binary file not shown
View
6 ga/genalg.c
@@ -198,9 +198,9 @@ float WholeFit(CodeType Code)
/* 100110011001 */
for (l=0; l<CodeSize; l++)
- Tot += fitness(Code[l]);
- //if (((l % 4 == 0 || l % 4 == 3) && Code[l] == 1.0) || ((l % 4 == 1 || l % 4 == 2) && Code[l] == 0.0))
- // Tot += 1.0;
+ //Tot += fitness(Code[l]);
+ if (((l % 4 == 0 || l % 4 == 3) && Code[l] == 1.0) || ((l % 4 == 1 || l % 4 == 2) && Code[l] == 0.0))
+ Tot += 1.0;
return Tot;
}
View
BIN  ga/word
Binary file not shown
View
137 ga/word.c
@@ -0,0 +1,137 @@
+#pragma warning(disable:4786) // disable debug warning
+
+#include <iostream> // for cout etc.
+#include <vector> // for vector class
+#include <string> // for string class
+#include <algorithm> // for sort algorithm
+#include <time.h> // for random seed
+#include <math.h> // for abs()
+
+#define GA_POPSIZE 2048 // ga population size
+#define GA_MAXITER 16384 // maximum iterations
+#define GA_ELITRATE 0.10f // elitism rate
+#define GA_MUTATIONRATE 0.25f // mutation rate
+#define GA_MUTATION RAND_MAX * GA_MUTATIONRATE
+#define GA_TARGET std::string("Hello world!")
+
+using namespace std; // polluting global namespace, but hey...
+
+struct ga_struct
+{
+ string str; // the string
+ unsigned int fitness; // its fitness
+};
+
+typedef vector<ga_struct> ga_vector;// for brevity
+
+void init_population(ga_vector &population,
+ ga_vector &buffer )
+{
+ int tsize = GA_TARGET.size();
+
+ for (int i=0; i<GA_POPSIZE; i++) {
+ ga_struct citizen;
+
+ citizen.fitness = 0;
+ citizen.str.erase();
+
+ for (int j=0; j<tsize; j++)
+ citizen.str += (rand() % 90) + 32;
+
+ population.push_back(citizen);
+ }
+
+ buffer.resize(GA_POPSIZE);
+}
+
+void calc_fitness(ga_vector &population)
+{
+ string target = GA_TARGET;
+ int tsize = target.size();
+ unsigned int fitness;
+
+ for (int i=0; i<GA_POPSIZE; i++) {
+ fitness = 0;
+ for (int j=0; j<tsize; j++) {
+ fitness += abs(int(population[i].str[j] - target[j]));
+ }
+
+ population[i].fitness = fitness;
+ }
+}
+
+bool fitness_sort(ga_struct x, ga_struct y)
+{ return (x.fitness < y.fitness); }
+
+inline void sort_by_fitness(ga_vector &population)
+{ sort(population.begin(), population.end(), fitness_sort); }
+
+void elitism(ga_vector &population,
+ ga_vector &buffer, int esize )
+{
+ for (int i=0; i<esize; i++) {
+ buffer[i].str = population[i].str;
+ buffer[i].fitness = population[i].fitness;
+ }
+}
+
+void mutate(ga_struct &member)
+{
+ int tsize = GA_TARGET.size();
+ int ipos = rand() % tsize;
+ int delta = (rand() % 90) + 32;
+
+ member.str[ipos] = ((member.str[ipos] + delta) % 122);
+}
+
+void mate(ga_vector &population, ga_vector &buffer)
+{
+ int esize = GA_POPSIZE * GA_ELITRATE;
+ int tsize = GA_TARGET.size(), spos, i1, i2;
+
+ elitism(population, buffer, esize);
+
+ // Mate the rest
+ for (int i=esize; i<GA_POPSIZE; i++) {
+ i1 = rand() % (GA_POPSIZE / 2);
+ i2 = rand() % (GA_POPSIZE / 2);
+ spos = rand() % tsize;
+
+ buffer[i].str = population[i1].str.substr(0, spos) +
+ population[i2].str.substr(spos, esize - spos);
+
+ if (rand() < GA_MUTATION) mutate(buffer[i]);
+ }
+}
+
+inline void print_best(ga_vector &gav)
+{ cout << "Best: " << gav[0].str << " (" << gav[0].fitness << ")" << endl; }
+
+inline void swap(ga_vector *&population,
+ ga_vector *&buffer)
+{ ga_vector *temp = population; population = buffer; buffer = temp; }
+
+int main()
+{
+ srand(unsigned(time(NULL)));
+
+ ga_vector pop_alpha, pop_beta;
+ ga_vector *population, *buffer;
+
+ init_population(pop_alpha, pop_beta);
+ population = &pop_alpha;
+ buffer = &pop_beta;
+
+ for (int i=0; i<GA_MAXITER; i++) {
+ calc_fitness(*population); // calculate fitness
+ sort_by_fitness(*population); // sort them
+ print_best(*population); // print the best one
+
+ if ((*population)[0].fitness == 0) break;
+
+ mate(*population, *buffer); // mate the population together
+ swap(population, buffer); // swap buffers
+ }
+
+ return 0;
+}
View
BIN  geneticalgorithm.odt
Binary file not shown
View
BIN  geneticalgorithm.zip
Binary file not shown
View
27 geneticalgorithm/GeneticAlgorithm/Program.cs
@@ -1,4 +1,27 @@
-using System;
+/*
+ * Chris Durtschi
+ * Artificial Intelligence
+ * Genetic Algorithm
+ *
+ *
+ *
+ * This program attemps to evolve a word the user chooses
+ * starting from a population of random words.
+ * It weighs the fitness of a word by how many letters
+ * are *exactly* correct. A correct letter gets a 1,
+ * and incorrect letter gets a 0.
+ *
+ * This algorithm seems to work fine for short words,
+ * of 5 letters or less. For larger words, it didn't do so well.
+ *
+ * This is probably not the ideal application for a genetic algorithm.
+ * It has a very specific goal (there is a best solution - find the correct word).
+ * There is only a single property to compare the fitness of the solution,
+ * but 26 different variations on that property.
+ *
+ */
+
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -21,7 +44,7 @@ static void Main(string[] args)
Console.Out.WriteLine("Word must contain only letters A-Z");
}
- WordGuesser guesser = new WordGuesser(10, 20, 0.5, 0.5, 0.5);
+ WordGuesser guesser = new WordGuesser(1000, 10000, 0.2, 0.6);
guesser.Guess(word);
Console.In.ReadLine();
View
12 geneticalgorithm/GeneticAlgorithm/Word.cs
@@ -1,4 +1,10 @@
-using System;
+/*
+ * Chris Durtschi
+ * Artificial Intelligence
+ * Genetic Algorithm
+ */
+
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -30,9 +36,9 @@ public Word(char[] letters)
public int CompareTo(Word other)
{
if (this.Fitness < other.Fitness)
- return -1;
- else if (this.Fitness > other.Fitness)
return 1;
+ else if (this.Fitness > other.Fitness)
+ return -1;
else
return 0;
}
View
119 geneticalgorithm/GeneticAlgorithm/WordGuesser.cs
@@ -1,4 +1,10 @@
-using System;
+/*
+ * Chris Durtschi
+ * Artificial Intelligence
+ * Genetic Algorithm
+ */
+
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -13,16 +19,16 @@ public class WordGuesser
double _mutationProbability;
int _totalFitness;
+ string _word;
char[] _letters;
List<Word> _population;
Random _rng = new Random();
- public WordGuesser(int populationSize, int maxGenerations, double replacementProbability, double crossoverProbability, double mutationProbability)
+ public WordGuesser(int populationSize, int maxGenerations, double crossoverProbability, double mutationProbability)
{
if (populationSize <= 0)
throw new ArgumentException("Population size and max generations must be greater than 0");
- if (replacementProbability < 0.0 || replacementProbability > 1.0 ||
- crossoverProbability < 0.0 || crossoverProbability > 1.0 ||
+ if (crossoverProbability < 0.0 || crossoverProbability > 1.0 ||
mutationProbability < 0.0 || mutationProbability > 1.0)
throw new ArgumentException("Probabilities must be between 0.0 and 1.0");
@@ -34,26 +40,36 @@ public WordGuesser(int populationSize, int maxGenerations, double replacementPro
public string Guess(string word)
{
- _letters = word.ToLower().ToCharArray();
- this.InitializePopulation();
+ _word = word;
+ _letters = _word.ToLower().ToCharArray();
+ _population = this.InitializePopulation();
this.CalculateFitnessOfPopulation();
- this.Reproduce();
+ for (int i = 0; i < _maxGenerations; i++)
+ {
+ this.Reproduce();
+ int crossovers = this.Crossover();
+ int mutations = this.Mutate();
+ this.CalculateFitnessOfPopulation();
+ Console.Out.WriteLine(String.Format("Crossovers: {0}; Mutations: {1}; Fitness: {2}; Best: {3}", crossovers, mutations, _population[0].Fitness, _population[0].ToString()));
+ if (_population[0].ToString() == _word)
+ {
+ Console.Out.WriteLine("Solution found in " + (i + 1) + " generations");
+ break;
+ }
+ }
return String.Empty;
}
- void InitializePopulation()
+ List<Word> InitializePopulation()
{
- // a = 97, z = 122
- _population = new List<Word>();
+ List<Word> population = new List<Word>();
for (int i = 0; i < _populationSize; i++)
{
- char[] word = new char[_letters.Length];
- for (int j = 0; j < _letters.Length; j++)
- word[j] = Convert.ToChar(_rng.Next(97, 122));
- _population.Add(new Word(word));
+ population.Add(this.GetRandomWord());
}
+ return population;
}
void CalculateFitnessOfPopulation()
@@ -69,24 +85,25 @@ void CalculateFitnessOfPopulation()
void Reproduce()
{
- // Select random fitness at which to survive.
- // Replace all losers with random copies of winners.
-
- int randomFitness = _rng.Next(_totalFitness);
- int cutoff;
+ int cutoff = _rng.Next(_totalFitness);
+ int totalFitness = 0;
+ int i;
- for (cutoff = 0; cutoff < _populationSize; cutoff++)
+ for (i = 0; i < _populationSize; i++)
{
- if (_population[cutoff].Fitness > cutoff)
+ totalFitness += _population[i].Fitness;
+ if (cutoff < totalFitness)
break;
}
-
- for (int i = cutoff; i < _populationSize; i++)
- _population[i] = this.GetRandomMemberOfPopulation(_population.GetRange(0, cutoff));
+
+ for (int j = i; j < _populationSize; j++)
+ _population[j] = this.GetRandomWord();
}
- void Crossover()
+ int Crossover()
{
+ int crossovers = 0;
+
foreach (Word word in _population)
{
if (_rng.NextDouble() > _crossoverProbability)
@@ -98,7 +115,8 @@ void Crossover()
randomWord = this.GetRandomMemberOfPopulation(_population);
} while (randomWord == word);
- int crossover = _rng.Next(1, _letters.Length - 2);
+ crossovers++;
+ int crossover = _rng.Next(1, _letters.Length - 1);
for (int i = 0; i < _letters.Length; i++)
{
if (i >= crossover)
@@ -109,11 +127,25 @@ void Crossover()
}
}
}
+
+ return crossovers;
}
- void Mutate()
+ int Mutate()
{
+ int mutations = 0;
+
+ foreach (Word word in _population)
+ {
+ if (_rng.NextDouble() > _mutationProbability)
+ continue;
+ mutations++;
+ int randomIndex = _rng.Next(0, _letters.Length - 1);
+ word.Letters[randomIndex] = this.GetRandomLetter();
+ }
+
+ return mutations;
}
int Fitness(char[] letters)
@@ -121,15 +153,44 @@ int Fitness(char[] letters)
int fitness = 0;
for (int i = 0; i < _letters.Length; i++)
{
- fitness += Math.Abs(Convert.ToInt32(letters[i]) - Convert.ToInt32(_letters[i]));
+ //fitness += Math.Abs(Convert.ToInt32(letters[i]) - Convert.ToInt32(_letters[i]));
+ if (letters[i] == _letters[i])
+ fitness += 1;
}
return fitness;
}
Word GetRandomMemberOfPopulation(List<Word> population)
{
- int randomIndex = _rng.Next(population.Count - 1);
+ int randomIndex = _rng.Next(0, population.Count - 1);
return population[randomIndex];
}
+
+ Word GetRandomMemberOfPopulation(List<Word> population, int totalFitness)
+ {
+ int randomFitness = _rng.Next(totalFitness);
+ int fitnessCounter = 0;
+ foreach (Word word in population)
+ {
+ fitnessCounter += word.Fitness;
+ if (fitnessCounter >= randomFitness)
+ return word;
+ }
+ return null;
+ }
+
+ Word GetRandomWord()
+ {
+ char[] word = new char[_letters.Length];
+ for (int j = 0; j < _letters.Length; j++)
+ word[j] = this.GetRandomLetter();
+ return new Word(word);
+ }
+
+ char GetRandomLetter()
+ {
+ // a = 97, z = 122
+ return Convert.ToChar(_rng.Next(97, 122));
+ }
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.