My program deals with the Genetic Algorithm and Hill Climber Algorithm. I have a program that compiles without any errs, its just the data is gives is incorrect. I explain my error on the bottom part of my post
Header File
#include <iostream>
using namespace std;
//------------------------------------------------------------------------------
template<class T>
class redefinedVector
{
public:
redefinedVector();
int get_size() const;
int get_capacity() const;
void push_back(T);
void pop();
void resize();
void print();
T& operator[](int index);
~redefinedVector();
private:
T *basket;
int capacity, size;
};
//------------------------------------------------------------------------------
class Individual
{
public:
friend class GeneticAlgorithm;
friend class HillClimberAlgorithm;
friend class UserInterface;
Individual();
Individual(int problem);
double randomization(double, double);
double GetData(int index) const;
double GetFitness() const
{
return fitness;
}
void SetProblem(int problem);
void MathProblemsFitness();
void setData(int index,double numbers);
int getProblem()const
{
return problem;
}
private:
double data[30];
double fitness;
double max;
double min;
int problem;
};
//------------------------------------------------------------------------------
class UserInterface
{
public:
UserInterface();
UserInterface(bool parameters, bool Problem, bool Optimization);
void setTimeResult(int,int);
void setDataResult(int,Individual);
Individual GetDataResult(int)const;
int getTimeResult(int) const;
private:
int highestTimes [3];
Individual best [3];
};
//------------------------------------------------------------------------------
class GeneticAlgorithm
{
friend class UserInterface;
public:
GeneticAlgorithm();
GeneticAlgorithm(int,int,double,double);
redefinedVector<Individual> individualResults;
redefinedVector<int> iterationVector;
redefinedVector<Individual> mainVector;
int selection(int);
int randomization(int,int);
int checkAnswer();
int rando(double);
double randomizationDouble(double min, double max);
void Breed(int,int,int,double,double);
void replace(Individual);
void Optimize(int, int,double,double);
private:
int parent1, parent2;
int iterationNumber;
};
//------------------------------------------------------------------------------
class HillClimberAlgorithm
{
public:
HillClimberAlgorithm ();
HillClimberAlgorithm(int problem, double mutation_chance, double mutation_amount);
redefinedVector<Individual> finalHillClimber;
redefinedVector<int>runTime;
redefinedVector<Individual> hillVector;
int randomization(int,int);
int checkAnswer();
int rando(double mutation_rate);
double randomizationDouble(double min, double max);
void replace(Individual individual);
private:
int inidividualA, individualB;
int counter;
double fitness;
};
Implementation
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <string.h>
#include <fstream>
#include <sstream>
#include <stdexcept>
#include <stdio.h>
#include <ctype.h>
#include <vector>
#include <cctype>
#include <algorithm>
#include <iterator>
#include <iomanip>
#include <cstdlib>
#include <iostream>
#include <math.h>
#include "bpt0004_3.h"
using namespace std;
using std :: ifstream;
using std :: ofstream;
using std :: endl;
template<class T>
redefinedVector<T>::redefinedVector() :capacity(2), size(0)
{
basket = new T [capacity];
}
template<class T>
void redefinedVector<T>::push_back(T element)
{
if(size < capacity)
{
basket[size] = element;
size++;
}
else
{
resize();
basket[size] = element;
size++;
}
}
template<class T>
T& redefinedVector<T>::operator[](int index)
{
if(index >= size)
{
cout << "Illegal index." << endl;
exit(0);
}
return basket[index];
}
template<class T>
void redefinedVector<T>::pop()
{
if(size != 0)
{
size--;
capacity = size + 1;
T *newBasket = new T[capacity];
for(int i = 0; i < size; i++)
{
newBasket[i] = basket[i];
}
delete [] basket;
basket = newBasket;
}
else
{
cout << "Vector is Empty." << endl;
}
}
template<class T>
redefinedVector<T>::~redefinedVector()
{
delete [] basket;
}
template<class T>
void redefinedVector<T>::resize()
{
T *newBasket = new T[capacity + 2];
for(int i = 0; i < size; i++)
{
newBasket[i] = basket[i];
}
delete [] basket;
basket = newBasket;
capacity += 2;
}
template<class T>
void redefinedVector<T>::print()
{
for(int i = 0; i < size; i++)
{
cout << basket[i] << " ";
}
}
template<class T>
int redefinedVector<T>::get_size() const
{
return size;
}
template<class T>
int redefinedVector<T>::get_capacity() const
{
return capacity;
}
//-----------------------------------------------------------------------------
UserInterface::UserInterface()
{
}
int UserInterface::getTimeResult(int index)const
{
return highestTimes[index];
}
void UserInterface::setTimeResult(int index, int numbers)
{
highestTimes[index] = numbers;
}
Individual UserInterface::GetDataResult(int index)const
{
return best[index];
}
void UserInterface::setDataResult(int index, Individual indiv)
{
best[index] = indiv;
}
UserInterface::UserInterface(bool parameters, bool Problem, bool Optimization)
{
/*
UserInterface Method that is the main menu for the user. Each bool parameter
ensures that values are entered into various parts within the menu.
*/
srand (time(0));
bool sc = false;
bool ro = false;
bool gr = false;
int userChoice = 0;
int populationSize= 0;
int problem =0;
int algoChoice=0;
double mutation_amount=0;
double mutation_rate=0;
bool menuBool=true;
while(userChoice != 6)
{
do{
cout << "Function Optimizer:\n"
<< "\n"
<< "1. Choose Algorithm \n"
<< "2. Choose Algorithm Parameters\n"
<< "3. Choose Problem (Schwefel, Rosenbrock, Griewangk).\n"
<< "4. Perform Optimization\n"
<< "5. Show All Optimization Results\n"
<< "6. Exit the System\n"
<< "\n"
<< "";
if(!(cin >> userChoice))
{
cout << endl;
cout << "Unknown Value!" << endl;
exit(0);
}
cout << endl;
}
while(userChoice > 6 || userChoice < 1);
if(userChoice ==1)
{
do
{
cout << "Enter Algorithm Choice\n"
<< "1. HillClimber\n"
<< "2. GeneticAlgorithm\n"
<< endl;
if (!(cin >>algoChoice))
{
cout << endl;
cout << "Unknown Value!" <<endl;
exit(0);
}
if (algoChoice==1)
cout <<"Hill Climber Chosen \n"
<<"";
if (algoChoice==2)
cout <<"GeneticAlgorithm Chosen\n"
<<"";
}
while((algoChoice < 0)&&(algoChoice >2));
}
if(userChoice == 2)
{
cout <<"Enter parameters for each algorithm. Only the mutation amount and mutation\n"
<<"chance will be used for the Hillclimber, the Genetic will take in the muation \n"
<<"chance, mutation amount, and population size.\n"
<<"\n";
do{
cout << "Enter Mutation Amount(.03-1.0): ";
if(!(cin >> mutation_amount))
{
cout << endl;
cout << "Unknown Value!" << endl;
exit(0);
}
cout << endl;
}
while(mutation_amount < -1);
do{
cout << "Enter Mutation Rate (.03-.25): ";
if(!(cin >> mutation_rate))
{
cout << endl;
cout << "Unknown Value!" << endl;
exit(0);
}
cout << endl;
}while(mutation_rate < -1);
do{
cout << "Enter Population Size (2-50): ";
if(!(cin >> populationSize))
{
cout << endl;
cout << "Unknown Value!" << endl;
exit(0);
}
cout << endl;
}
while(populationSize < 2);
parameters = true;
}
else if(userChoice == 3)
{
do{
cout << "Choose a problem (Schwefel, Rosenbrock, Griewangk)." << endl;
cout << "1 Schwefel" << endl;
cout << "2 Rosenbrock" << endl;
cout << "3 Griewangk" << endl;
if(!(cin >> problem))
{
cout << endl;
cout << "Unknown Value!" << endl;
exit(0);
}
cout << endl;
if(problem == 1)
{
sc = true;
}
else if(problem == 2)
{
ro = true;
}
else if(problem == 3)
{
gr = true;
}
}while(problem > 3 || problem < 1);
Problem = true;
}
else if(userChoice == 4)
{
if(!parameters || !Problem)
{
cout << "Error" << endl << endl;
}
if (algoChoice==1)
{
HillClimberAlgorithm(problem, mutation_rate, mutation_amount);
Optimization = true;
}
else if (algoChoice==2)
{
GeneticAlgorithm(problem,populationSize,mutation_rate,mutation_amount);
Optimization = true;
}
}
else if(userChoice == 5)
{
if(!Optimization)
{
cout << "Optimization not run" << endl << endl;
}
else
{
if(sc == true)
{
cout <<"Iterations: " << highestTimes[0] <<"\n";
}
else
{
cout << "Schwefel information empty\n"
<<" " ;
}
if(ro == true)
{
cout <<"Iterations: " << highestTimes[1] <<"\n";
}
else
{
cout << "Rosenbrock information empty\n"
<< " " ;
}
if(gr == true)
{
cout <<"Iterations: " << highestTimes[2] <<"\n";
}
else
{
cout << "Griewangk information empty" << endl << endl;
}
}
}
else if(userChoice == 6)
{
cout << "Exiting" << endl;
exit(0);
}
}
}
//------------------------------------------------------------------------------
HillClimberAlgorithm::HillClimberAlgorithm()
{
}
void HillClimberAlgorithm::replace(Individual newIndividual)
/*Replace takes the least fit individual and replaces it the the newIndividual
Pre-condition: takes in a newIndividual of type Individual, which sets a vector of random integers between a range
determined by the problem.
Post-condition replaces the current individual at hillvector[i] with the newIndividual
*/
{
double temp = hillVector[0].GetFitness();
int index = 0;
for(int i = 1; i < hillVector.get_size(); i++)
{
if(temp < hillVector[i].GetFitness())
{
temp = hillVector[i].GetFitness();
index = i;
}
}
for(int i = 0; i < 30; i++)
{
hillVector[index].setData(i,newIndividual.GetData(i));
hillVector[index].MathProblemsFitness();
}
counter++;
}
int HillClimberAlgorithm::rando(double mutation_rate)
/*
Pre-condition: user entered mutation_rate
Post-condition: generates a random double based on the mutation_rate
*/
{
double number = rand() / (double)RAND_MAX;
return number < mutation_rate;
}
int HillClimberAlgorithm::randomization(int min, int max)
/*
Pre-condition: 2 integers
Post-condition: random generated integer between the range of min and max
*/
{
return static_cast<int>(( static_cast<double>(rand()))/ static_cast<double>( RAND_MAX) *(max-min + 1) + min);
}
double HillClimberAlgorithm::randomizationDouble(double min, double max)
/*
Pre-condition: 2 double
Post-condition: random generated double between the range of min and max
*/
{
return static_cast<double>(rand())/ static_cast<double>( RAND_MAX) *(max-min + 1) + min;
}
HillClimberAlgorithm::HillClimberAlgorithm(int problem, double mutation_rate, double mutation_amount)
/*
Main constructor used in the HillClimber Algorithm
Pre-condition: takes in three parameters: problem, mutation_rate, mutation_amount
Post-condition: Passes the Individual through the MathProblemsFitness and generates a fitness,
if the fitness is less than the current fitness, than the newIndividual replaces individual
*/
{
Individual newIndividualA(problem);
fitness= newIndividualA.GetFitness();
double range=0;
if(problem == 1)
{
range = 131.072;
}
else if(problem == 2)
{
range = 4.096;
}
else
{
range = 1200;
}
while( fitness < .1)
{
int chance = 0;
int choice = rando(mutation_rate);
int selection = 0;
selection = randomization(1,2);
Individual newIndividualB;
for(int i = 0; i < 30; i++)
{
if(choice == 1)
{
double newData = hillVector[selection].GetData(i); //get the data from the chosen parent
newData = newData + range*(randomizationDouble(0,2)-1)*mutation_amount; //mutate it occording to the formula
newIndividualB.setData(i,newData); //set the new data into the corresponding index of the child object
if(newData > range/2) //if the number goes out of the upper bounds
{
newIndividualB.setData(i,range/2);
}
else if(newData < ((range/2)*-1)) //if the number gooes out of the lower bounds
{
newIndividualB.setData(i,((range/2)*-1));
}
}
else
{
newIndividualB.setData(i,hillVector[selection].GetData(i));
}
}
int iterations=0;
for (int i=0; i < 30; i++)
{
Individual newIndividualB (problem);
newIndividualB.setData(i,newIndividualB.GetData(i)+newIndividualB.GetData(i)*((static_cast<double>(rand())/ static_cast<double>( RAND_MAX) *(2-0 + 1) + 0))*mutation_amount);
double newFitness=newIndividualB.GetFitness();
iterations++;
if (newFitness < fitness)
{ newIndividualB.MathProblemsFitness();
replace(newIndividualB);
}
cout << iterations << endl;
}
}
}
//------------------------------------------------------------------------------
Individual::Individual()
{
}
double Individual::GetData(int index) const
{
return data[index];
}
void Individual::setData(int index, double numbers)
{
data[index] = numbers;
}
void Individual::SetProblem(int Problem)
{
problem = Problem;
}
Individual::Individual(int problem)
/*
Creates a new individual, and based on the problem, enters random values into
a vector and passes that vector through MathProblemsFitness to create a fitness
Pre-condition:user entered problem
Post-condition: New individual created based on the problem choice and a fitness calculated
*/
{
SetProblem(problem);
if(problem == 1)
{
for(int i = 0; i < 30; i++)
{
data[i] = randomization(-65.536,65.536);
}
}
else if(problem == 2)
{
for(int i = 0; i < 30; i++)
{
data[i] = randomization(-2.048,2.048);
}
}
else if(problem == 3)
{
for(int i = 0; i < 30; i++)
{
data[i] = randomization(-600,600);
}
}
MathProblemsFitness();
}
double Individual::randomization(double min, double max)
{
return static_cast<double>(rand())/ static_cast<double>( RAND_MAX) *(max-min + 1) + min;
}
void Individual::MathProblemsFitness()
/*
MathProblemsFitness defines the three math probelems (Schwefel, Rosenbrock, Griewangk)
each vector from individual passes through these problems to calculate a fitness
*/
{
double holder = 0;
double temp2 = 1;
fitness = 0;
int next = 1;
if(problem == 1)
{
for(int i = 0; i < 30; i++)
{
holder = 0;
for(int j = 0; j < next; j++)
{
holder = holder + data[j];
}
next++;
fitness = fitness + (holder*holder);
}
}
else if(problem == 2)
{
for(int i = 0; i < 29; i++)
{
holder = 0;
holder = 100*(data[i+1]-(data[i]*data[i]))*(data[i+1]-(data[i]*data[i])) + (data[i] - 1)*(data[i] - 1);
fitness = fitness + holder;
}
}
else if(problem == 3)
{
for(int i = 0; i < 30; i++)
{
holder = 0;
holder = (data[i]*data[i])/4000;
fitness = fitness+ holder;
}
fitness = fitness + 1;
for(int i = 0; i < 30; i++)
{
holder = 0;
holder = cos(data[i]/sqrt(i+1));
temp2 = temp2 * holder;
}
fitness = fitness - temp2;
}
}
//------------------------------------------------------------------------------
GeneticAlgorithm::GeneticAlgorithm()
{
}
GeneticAlgorithm::GeneticAlgorithm(int problem, int populationSize, double mutation_rate, double mutation_amount)
/*
Builds the population of individuals and pushes it into the mainVector, then loop through 5 times
until the desired value is reached.
*/
{
UserInterface m;
int iterations;
for(int i = 0; i < 5; i++)
{
iterationNumber = 0;
for(int i = 0; i < populationSize; i++)
{
Individual I(problem);
mainVector.push_back(I);
}
int foundIt = 0;
checkAnswer();
while(foundIt == 0 && iterationNumber < 5000000)
{
foundIt = checkAnswer();
Optimize(problem, populationSize,mutation_rate, mutation_amount);
foundIt++;
}
int index = 0;
double temp = mainVector[0].GetFitness();
for(int i = 1; i < mainVector.get_size(); i++)
{
if(temp > mainVector[i].GetFitness())
{
temp = mainVector[i].GetFitness();
index = i;
}
}
individualResults.push_back(mainVector[index]);
iterationVector.push_back(iterationNumber);
if(problem == 1)
{
if(iterationNumber < m.getTimeResult(0))
{
m.setTimeResult(0,iterationNumber);
m.setDataResult(0,mainVector[index]);
}
}
else if(problem == 2)
{
if(iterationNumber < m.getTimeResult(1))
{
m.setTimeResult(1,iterationNumber);
m.setDataResult(1,mainVector[index]);
}
}
else
{
if(iterationNumber < m.getTimeResult(2))
{
m.setTimeResult(2,iterationNumber);
m.setDataResult(2,mainVector[index]);
}
}
for(int i = 0; i < populationSize; i++)
{
mainVector.pop();
}
}
cout << endl;
cout << "Results: \n"
<< "\n"
<< "";
for(int i = 0; i < individualResults.get_size(); i++)
{
cout << endl;
cout << "Individual Best: ";
for(int j = 0; j < 30; j++)
{
cout << individualResults[i].data[j] << "\n"
<<"";
}
cout << "\n"
<< "Fitness Level: " << individualResults[i].GetFitness() << "\n"
<< "Iterations: " << iterationVector[i] << endl;
}
for(int i = 0; i < individualResults.get_size(); i++)
{
individualResults.pop();
iterationVector.pop();
}
cout << endl;
}
void GeneticAlgorithm::Optimize(int problem, int populationSize, double mutRate, double mutAmount)
{
parent1 = selection(populationSize);
parent2= selection(populationSize);
Breed(parent1,parent2,problem,mutRate,mutAmount);
}
void GeneticAlgorithm::Breed(int parent1, int parent2, int problem, double mutation_rate,double mutation_amount)
{
Individual child(problem);
double range = 0;
if(problem == 1)
{
range = 131.072;
}
else if(problem == 2)
{
range = 4.096;
}
else
{
range = 1200;
}
for(int i = 0; i < 30; i++)
{
int selection = 0;
selection = randomization(1,2);
if(selection == 1)
{
selection = parent1;
}
else
{
selection = parent2;
}
int chance = 0;
int choice = rando(mutation_rate);
if(choice == 1)
{
double newData = mainVector[selection].GetData(i);
newData = newData + range*(randomizationDouble(0,2)-1)*mutation_amount;
child.setData(i,newData);
if(newData > range/2)
{
child.setData(i,range/2);
}
else if(newData < ((range/2)*-1))
{
child.setData(i,((range/2)*-1));
}
}
else
{
child.setData(i,mainVector[selection].GetData(i));
}
}
child.SetProblem(mainVector[parent1].getProblem());
child.MathProblemsFitness();
replace(child);
}
int GeneticAlgorithm::rando(double mutRate)
{
double number = rand() / (double)RAND_MAX;
return number < mutRate;
}
void GeneticAlgorithm::replace(Individual child)
{
double temp = mainVector[0].GetFitness();
int index = 0;
for(int i = 1; i < mainVector.get_size(); i++)
{
if(temp < mainVector[i].GetFitness())
{
temp = mainVector[i].GetFitness();
index = i;
}
}
for(int i = 0; i < 30; i++)
{
mainVector[index].setData(i,child.GetData(i));
mainVector[index].MathProblemsFitness();
}
iterationNumber++;
while (iterationNumber ==0)
//if(iterationNumber %100 == 0)
{
temp = mainVector[0].GetFitness();
for(int i = 1; i < mainVector.get_size(); i++)
{
if(temp > mainVector[i].GetFitness())
{
temp = mainVector[i].GetFitness();
}
}
cout << "Best Fitness: " << iterationNumber <<" " << temp <<endl;
}
}
int GeneticAlgorithm::checkAnswer()
{
for(int i = 0; i < mainVector.get_size(); i++)
{
if(mainVector[i].GetFitness() < .1)
{
return 1;
}
else
{
return 0;
}
}
}
int GeneticAlgorithm::selection(int populationSize)
{
int choice = rand() % populationSize;
int choice2 = rand() % populationSize;
if(mainVector[choice].GetFitness() < mainVector[choice2].GetFitness())
{
return choice;
}
else
return choice2;
}
int GeneticAlgorithm::randomization(int min, int max)
{
return static_cast<int>(( static_cast<double>(rand()))/ static_cast<double>( RAND_MAX) *(max-min + 1) + min);
}
double GeneticAlgorithm::randomizationDouble(double min, double max)
{
return static_cast<double>(rand())/ static_cast<double>( RAND_MAX) *(max-min + 1) + min;
}
and Main
#include <iostream>
#include "bpt0004_3.h"
using namespace std;
int main()
{
bool parameters = false, Problem = false, Optimization = false;
UserInterface(parameters, Problem, Optimization);
return 0;
}
My error:
1. first choose 1, then choose 2 for genetic algorithm
2. choose 2, then input parameters within the ranges given
3. choose 3, and choose 1(schwefel)
4. choose 4 to optimize
5. choose 5 <-----this displays the correct number of iterations
6. choose 3, and choose 2 or 1(Rosenbrock or Griewangk)
7. choose 4 to optimize
8. choose 5 <-----This displays the error
Error
Genetic Iterations Schwefel: -1209686560
Genetic Iterations Rosenbrock: 1
Genetic Iterations Griewangk: -1079226444
Why am i getting negative numbers and why is the iterations for rosenbrock just 1?? Please help me, this program is due tonight.