Prepared genetic functions and renamed class and struct for a more fitting name
This commit is contained in:
parent
b6da05660f
commit
03fe944c1c
113
src/chess.cpp
113
src/chess.cpp
@ -1,4 +1,5 @@
|
||||
#include "chess.hpp"
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
|
||||
@ -15,30 +16,32 @@ int GenerateRandomNumber(int generationLimit) {
|
||||
return generatedNumber;
|
||||
}
|
||||
|
||||
GeneticDefaults::GeneticDefaults(void) {
|
||||
size = 4;
|
||||
GeneticRules::GeneticRules(void) {
|
||||
boardSize = 4;
|
||||
populationSize = 1;
|
||||
}
|
||||
|
||||
GeneticDefaults::GeneticDefaults(unsigned int size) {
|
||||
this->size = size;
|
||||
GeneticRules::GeneticRules(unsigned int boardSize, unsigned int populationSize) {
|
||||
this->boardSize = boardSize;
|
||||
this->populationSize = populationSize;
|
||||
}
|
||||
|
||||
GeneticChess::GeneticChess(void) {
|
||||
Individual::Individual(const unsigned int boardSize) {
|
||||
generationCount = 0;
|
||||
InitializeGenerator();
|
||||
// population init part of vector resize
|
||||
board.resize(genetics.size, 0);
|
||||
board.resize(boardSize, 0);
|
||||
for (int i = 0; i < board.size(); ++i) {
|
||||
board.at(i) = GenerateRandomNumber(genetics.size);
|
||||
board.at(i) = GenerateRandomNumber(boardSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GeneticChess::Print(void) {
|
||||
void Individual::Print(void) {
|
||||
std::cout << generationCount << ':' << std::endl;
|
||||
for (int i : board) {
|
||||
std::cout << '[';
|
||||
for (int j = 0; j < genetics.size; ++j) {
|
||||
for (int j = 0; j < board.size(); ++j) {
|
||||
if (j == i) { std::cout << "Q"; }
|
||||
else { std::cout << ' '; }
|
||||
}
|
||||
@ -48,7 +51,7 @@ void GeneticChess::Print(void) {
|
||||
}
|
||||
|
||||
// Gets the fitness of the population
|
||||
unsigned int GeneticChess::GetFitness(void) {
|
||||
unsigned int Individual::GetFitness(void) {
|
||||
unsigned int fitness = 0;
|
||||
for (unsigned int i : board) {
|
||||
if (!IsQueenThreatened(i)) { fitness++; }
|
||||
@ -58,29 +61,101 @@ unsigned int GeneticChess::GetFitness(void) {
|
||||
}
|
||||
|
||||
//
|
||||
void GeneticChess::Selection(void) {
|
||||
void Individual::Selection(void) {
|
||||
/* TODO: Finish selection
|
||||
int fitness[N] = {0};
|
||||
int fitness_sum = 0;
|
||||
int i, j;
|
||||
// get fitness for all members of population
|
||||
for ( i=0; i<N; i++ ){
|
||||
fitness[i] = get_fitness(population[i]);
|
||||
fitness_sum += fitness[i];
|
||||
}
|
||||
|
||||
|
||||
// this is simple fitness proportional selection
|
||||
// (roulette wheel sampling)
|
||||
int roll;
|
||||
int temp_sum = 0;
|
||||
int selection;
|
||||
for ( i=0; i<N; i++ ){
|
||||
temp_sum = 0;
|
||||
roll = rand()%fitness_sum;
|
||||
for ( j=0; j<N; j++ ){
|
||||
temp_sum += fitness[j];
|
||||
if ( roll < temp_sum ){
|
||||
selection = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
selected[i] = selection;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Crossover on the population
|
||||
void GeneticChess::Crossover(void) {
|
||||
void Individual::Crossover(void) {
|
||||
/* TODO: Finish Crossover
|
||||
double crossover_roll;
|
||||
int crossover_locus;
|
||||
int i;
|
||||
unsigned char temp1;
|
||||
unsigned char temp2;
|
||||
unsigned char mask;
|
||||
unsigned char temp_population[N];
|
||||
|
||||
for ( i=0; i<N; i+=2){
|
||||
crossover_roll = ((double)rand())/((double)RAND_MAX);
|
||||
temp1 = 0;
|
||||
temp2 = 0;
|
||||
if(crossover_roll <= P_c){ //crossover
|
||||
crossover_locus = rand()%L;
|
||||
mask = get_mask(crossover_locus);
|
||||
temp1 = population[selected[i]] & mask;
|
||||
temp1 ^= population[selected[i+1]] & ~mask;
|
||||
temp2 = population[selected[i+1]] & mask;
|
||||
temp2 ^= population[selected[i]] & ~mask;
|
||||
temp_population[i] = temp1;
|
||||
temp_population[i+1] = temp2;
|
||||
}
|
||||
else{ //clone
|
||||
temp_population[i] = population[selected[i]];
|
||||
temp_population[i+1] = population[selected[i+1]];
|
||||
}
|
||||
}
|
||||
|
||||
//copy back to population
|
||||
for ( i=0; i<N; i++ ){
|
||||
population[i] = temp_population[i];
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Mutates the population
|
||||
void GeneticChess::Mutation(void) {
|
||||
|
||||
void Individual::Mutation(void) {
|
||||
/* TODO: Finish Mutation
|
||||
double mutation_roll;
|
||||
int i, j;
|
||||
for ( i=0; i<N; i++){
|
||||
for ( j=0; j<L; j++ ){
|
||||
mutation_roll = ((double)rand())/((double)RAND_MAX);
|
||||
if ( mutation_roll <= P_m ){
|
||||
population[i] ^= (1<<j); //toggle bit
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Checks if the passed in queen is threatened on the board
|
||||
// Impossible for queens to be threatened by same row
|
||||
bool GeneticChess::IsQueenThreatened(const unsigned int queenRow) {
|
||||
bool Individual::IsQueenThreatened(const int queenRow) {
|
||||
int queenCol = board.at(queenRow);
|
||||
int diffRow, diffCol;
|
||||
for (int i = 0; i < genetics.size; ++i) {
|
||||
if (i == queenRow) { continue; }
|
||||
diffCol = queenCol - board.at(i);
|
||||
diffRow = queenRow - i;
|
||||
for (int row = 0; row < board.size(); ++row) {
|
||||
if (row == queenRow) { continue; }
|
||||
diffCol = abs(queenCol - (int)board.at(row));
|
||||
diffRow = abs(queenRow - row);
|
||||
if (diffCol == 0) { return true; } // Column threat
|
||||
if (diffCol == diffRow) { return true; }
|
||||
}
|
||||
|
@ -6,28 +6,28 @@
|
||||
void InitializeGenerator(void);
|
||||
int GenerateRandomNumber(int generationLimit);
|
||||
|
||||
struct GeneticDefaults {
|
||||
struct GeneticRules {
|
||||
const float kProbabilityCrossover = 0.7; //crossover probability (typical val.)
|
||||
const float kProbabilityMutation = 0.001; //mutation probability (typical val.)
|
||||
const unsigned int generationLimit = 10000; //number of generations (something huge)
|
||||
unsigned int size; //population size (change to something even)
|
||||
GeneticDefaults(void);
|
||||
GeneticDefaults(unsigned int size); //custom generation sizes
|
||||
unsigned int boardSize; //board size
|
||||
unsigned int populationSize; //population size (change to something even)
|
||||
GeneticRules(void);
|
||||
GeneticRules(unsigned int boardSize, unsigned int populationSize); //custom generation sizes
|
||||
};
|
||||
|
||||
class GeneticChess {
|
||||
class Individual {
|
||||
public:
|
||||
std::vector<unsigned int> board;
|
||||
GeneticDefaults genetics;
|
||||
int generationCount;
|
||||
GeneticChess(void);
|
||||
Individual(const unsigned int boardSize);
|
||||
void Print(void);
|
||||
unsigned int GetFitness(void);
|
||||
void Selection(void);
|
||||
void Crossover(void);
|
||||
void Mutation(void);
|
||||
private:
|
||||
bool IsQueenThreatened(const unsigned int queenRow);
|
||||
bool IsQueenThreatened(const int queenRow);
|
||||
};
|
||||
|
||||
#endif // CHESS_HPP
|
||||
|
@ -1,13 +1,13 @@
|
||||
#include "chess.hpp"
|
||||
#include "genetic_algorithm.hpp"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <vector>
|
||||
|
||||
int main() {
|
||||
GeneticChess population;
|
||||
population.Print();
|
||||
population.GetFitness();
|
||||
GeneticRules genetics;
|
||||
std::vector<Individual> population;
|
||||
Individual person(genetics.boardSize);
|
||||
person.Print();
|
||||
person.GetFitness();
|
||||
|
||||
/*
|
||||
unsigned char population[N] = {0};
|
||||
|
Loading…
Reference in New Issue
Block a user