Skip to content

Commit

Permalink
Finished (solo falta documentación)
Browse files Browse the repository at this point in the history
  • Loading branch information
MrRobb committed Jan 21, 2018
1 parent 5b296cc commit 4fc043e
Show file tree
Hide file tree
Showing 9 changed files with 295 additions and 171 deletions.
1 change: 1 addition & 0 deletions Tetris AI/src/AI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// Tetris AI
//
// Created by Roberto Ariosa Hernández on 09/01/2018.
// Copyright © 2018 Mr.Robb. All rights reserved.
//

#include "AI.hpp"
Expand Down
9 changes: 5 additions & 4 deletions Tetris AI/src/AI.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// Tetris AI
//
// Created by Roberto Ariosa Hernández on 09/01/2018.
// Copyright © 2018 Mr.Robb. All rights reserved.
//

#ifndef AI_hpp
Expand All @@ -26,10 +27,10 @@ struct Shape {
};

class AI {
float aggregate_height = -3.78;
float complete_lines = 1.6;
float holes = -2.31;
float bumpiness = -0.59;
float aggregate_height = 0.132802;
float complete_lines = 0.132802;
float holes = -0.344799;
float bumpiness = -0.0387222;

vector< vector<unsigned char> > grid;
map<int,vector< vector<unsigned char> > > shapes;
Expand Down
3 changes: 3 additions & 0 deletions Tetris AI/src/DNA.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class DNA {
@brief Access the genes directly.
@pre i must be between 0 and lenght-1.
@param i Position of the gene.
@return The gene at position i.
*/
float& operator[](int i);

Expand All @@ -60,6 +61,7 @@ class DNA {
/**
@brief Get the fitness of the individual.
@pre Fitness function has been already executed.
@return The fitness of the individual.
@see DNA::fitness
*/
float getFitness();
Expand All @@ -68,6 +70,7 @@ class DNA {
@brief Creates a child with mixed genes via crossover.
@f$ itself + partner = child @f$
@param partner It will provide some genetic information.
@return The child.
*/
DNA crossover(DNA &partner);

Expand Down
119 changes: 67 additions & 52 deletions Tetris AI/src/Population.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,104 +8,119 @@

#include "Population.hpp"

Population::Population() {

}
Population::Population() {}

// construct
Population::Population(int length, float mutationRate, int N_ind, int generation) {
Population::Population(int N_genes, int N_ind, float mutationRate, unsigned int generation)
{
this->mutationRate = mutationRate;
this->generation = generation;
pool = vector<DNA> ();
population = vector<DNA> (N_ind, DNA());
for (int i = 0; i < N_ind; i++) {
population[i] = DNA(length);
}

for (int i = 0; i < N_ind; i++)
population[i] = DNA(N_genes);
}

DNA Population::operator[](int i) {
DNA& Population::operator[](int i)
{
return this->population[i];
}

// call fitness for every specimen
void Population::calculateFitness(vector<int> scores) {
void Population::calculateFitness(vector<int> scores)
{
int max_score = *max_element(scores.begin(), scores.end());
for (int i = 0; i < population.size(); i++) {

// Call fitness() for every Individual
for (int i = 0; i < population.size(); i++)
population[i].fitness(scores[i], max_score);
}
}

// reproduce
void Population::naturalSelection() {
int i = getBest();
float maxFitness = population[i].getFitness();

for (int i = 0; i < population.size(); i++) {
float relative_fitness = population[i].getFitness() / maxFitness;
int percentage = int(relative_fitness * 100);
for (int j = 0; j < percentage; j++) {
pool.push_back(population[i]);
}
}
}

// create new generation
Population Population::generate(int length) {
Population p (length, mutationRate, int(population.size()), generation + 1);
if (pool.size() > 0) {
Population Population::generate()
{
// Fill the temporary reproduction pool
naturalSelection();

// Create container of the next generation
int N_ind = int(population.size());
int N_genes = int(population[0].getValues().size());
Population p (N_genes, N_ind, mutationRate, generation + 1);

// Fill pool
if (pool.size() > 0)
{
for (int i = 0; i < population.size(); i++) {
int a = int(rand() % pool.size());
int b = int(rand() % pool.size());
DNA dna_a = this->pool[a];
DNA dna_b = this->pool[b];
DNA child = dna_a.crossover(dna_b);
child.mutate(mutationRate, generation+1);
child.mutate(mutationRate);
p.population[i] = child;
}

// Free pool
pool = vector<DNA>();
}

return p;
}

// most fit
int Population::getBest() {
int Population::getBest()
{
float record = 0.0;
int index = 0;
for (int i = 0; i < population.size(); i++) {
if (population[i].getFitness() > record) {

for (int i = 0; i < population.size(); i++)
{
float current = population[i].getFitness();

if (current > record) {
index = i;

record = population[i].getFitness();
record = current;
}
}

return index;
}

// finished
bool Population::isFinished() {
finished = (population[getBest()].getFitness() == perfectScore);
return finished;
}

int Population::getGenerations() {
int Population::getGenerations()
{
return generation;
}

float Population::getAverage() {
float Population::getAverage()
{
float total = 0.0;
for (int i = 0; i < population.size(); i++) {

for (int i = 0; i < population.size(); i++)
total += population[i].getFitness();
}

return total / (float) population.size();
}

vector< vector<float> > Population::allValues() {
vector< vector<float> > all (population.size(), vector<float> (4));
for (int i = 0; i < population.size(); i++) {
for (int j = 0; j < 4; j++) {
vector< vector<float> > Population::allValues()
{
int N_ind = int(population.size());
int N_genes = int(population[0].getValues().size());
vector< vector<float> > all (N_ind, vector<float> (N_genes));

for (int i = 0; i < N_ind; i++) {
for (int j = 0; j < N_genes; j++) {
all[i][j] = population[i][j];
}
}

return all;
}

void Population::naturalSelection()
{
for (int i = 0; i < population.size(); i++)
{
float fitness = population[i].getFitness();
int percentage = int(fitness * 100);

for (int j = 0; j < percentage; j++)
pool.push_back(population[i]);
}
}
86 changes: 65 additions & 21 deletions Tetris AI/src/Population.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,43 +17,87 @@
using namespace std;

class Population {
private:
float mutationRate;
vector<DNA> population;
vector<DNA> pool;
string target;
int generation;
bool finished;
int perfectScore;

public:
/**
@brief Creates an empty Population.
*/
Population();

// construct
Population(int length, float mutationRate, int N_ind, int generation);
/**
@brief Creates a Population with N_ind individuals with random genes.
@param N_genes Number of genes of each individual.
@param N_ind Number of individuals.
@param mutationRate Probability of mutating a gene, between 0 and 1.
@param generation Number of the generation.
*/
Population(int N_genes, int N_ind, float mutationRate, unsigned int generation);

DNA operator[](int i);
/**
@brief Access the individual directly.
@pre i must be between 0 and N_ind-1.
@param i Position of the Individual.
@return The individual at position i.
*/
DNA& operator[](int i);

// call fitness for every specimen
/**
@brief Calculates the fitness of the population.
@param scores Vector containing the scores of all of the individuals.
*/
void calculateFitness(vector<int> scores);

// reproduce
void naturalSelection();

// create new generation
Population generate(int length);
/**
@brief Generates the next generation.
@pre calculateFitness have already been executed.
@pre Population has at least one individual.
@return The next generation.
*/
Population generate();

// most fit
/**
@brief Get position of the fittest individual. In case of having more than one, the first one is returned.
@return The position of the fittest.
*/
int getBest();

// finished
bool isFinished();

/**
@brief Get the number of the generation.
@return The number of the generation.
*/
int getGenerations();

/**
@brief Get the average fitness of the population.
@return The average fitness of the population, between 0 and 1.
*/
float getAverage();

/**
@brief Get all of the genes of the individuals.
@return Vector of vector of genes. Each vector represents an individual. Each value represents a gene.
*/
vector< vector<float> > allValues();

private:

/// @brief Probability of mutation between 0 and 1.
float mutationRate;

/// @brief Contains all of the individuals.
vector<DNA> population;

/// @brief Creates a temporary reproduction pool.
vector<DNA> pool;

/// @brief Number of the generation.
unsigned int generation;

/**
@brief Fills the reproduction pool based on the fitness of every individual. The fittest have more probabilities of being selected out of the reproduction pool.
*/
void naturalSelection();

};

#endif /* Population_hpp */
Loading

0 comments on commit 4fc043e

Please sign in to comment.