Prepared genetic functions and renamed class and struct for a more fitting name

This commit is contained in:
TriantaTV 2023-09-24 19:42:08 -05:00
parent b6da05660f
commit 03fe944c1c
3 changed files with 111 additions and 36 deletions

View File

@ -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; }
}

View File

@ -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

View File

@ -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();
int main() {
GeneticRules genetics;
std::vector<Individual> population;
Individual person(genetics.boardSize);
person.Print();
person.GetFitness();
/*
unsigned char population[N] = {0};