Hi there daniweb, i'm making a program that deals with a hill climber and genetic algorithm. I'm pretty much done writing the code but i'm having a headache of a problem....heres the header
#include <iostream>
using namespace std;
template<class T>
class myVector
{
public:
myVector();
int get_size() const;
int get_capacity() const;
void push_back(T);
void pop();
void resize();
void print();
T& operator[](int index);
~myVector();
private:
T *basket;
int capacity, size;
};
template<class T>
myVector<T>::myVector() :capacity(2), size(0)
{
basket = new T [capacity];
}
template<class T>
void myVector<T>::push_back(T element)
{
if(size < capacity)
{
basket[size] = element;
size++;
}
else
{
resize();
basket[size] = element;
size++;
}
}
template<class T>
T& myVector<T>::operator[](int index)
{
if(index >= size)
{
cout << "Illegal index." << endl;
int i;
cin>>i;
exit(0);
}
return basket[index];
}
template<class T>
void myVector<T>::pop()
{
if(size != 0)
{
size--; //decrease the size
capacity = size + 1; //our new capacity is the size plus 1 extra space
T *newBasket = new T[capacity]; //copy over the contents
for(int i = 0; i < size; i++)
{
newBasket[i] = basket[i];
}
delete [] basket; //destroy our old array
basket = newBasket; //set new array to desired variable
}
else
{
cout << "Vector is Empty." << endl;
}
}
template<class T>
myVector<T>::~myVector()
{
delete [] basket;
}
template<class T>
void myVector<T>::resize()
{
T *newBasket = new T[capacity + 2]; //make new capacity increased by 2
for(int i = 0; i < size; i++) //copy over the contents to the new array
{
newBasket[i] = basket[i];
}
delete [] basket; //delete the old array
basket = newBasket; //set new array to desired variable name
capacity += 2; //increase current capacity by 2
}
template<class T>
void myVector<T>::print()
{
for(int i = 0; i < size; i++)
{
cout << basket[i] << " ";
}
}
template<class T>
int myVector<T>::get_size() const
{
return size;
}
template<class T>
int myVector<T>::get_capacity() const
{
return capacity;
}
class Individual
{
friend class HillClimberAlgorithm;
friend class GeneticAlgorithm;
friend class UserInterface;
public:
Individual();
Individual (int problem);
Individual(int Algorithm,int Problem, double mutationChance, double mutationAmount);
void SetProblem(int Problem);
void SetAlgorithm(int Algorithm);
void SetParameters(double mutationChance, double mutationAmonut);
void SetParameters (double populationSize, double mutationRate, double mutationAmount);
int GetProblem() const;
int GetAlgorithm() const;
void MathProblemsFitness();
double GetFitness() const;
double GetData(int i) const;
void SetData(int i, double numbers) ;
private:
int problem;
double data[30];
int algorithm;
double mutation_chance;
double mutation_amount;
double individualFitness;
};
class UserInterface
/*
The user interface class is used primarily for the menu of the program. The user
is presented with a menu and throughout the use of the program, loops through the
menu until the user decides to quit.
*/
{
public:
friend class Individual;
UserInterface();
void MainMenu();
bool get_number ( int& number );
void SetDataResult(int,Individual);
Individual GetDataResult(int);
void SetTimeResult(int,int);
int GetTimeResult(int);
private:
bool menuBool;
int inputNumber;
int problemChoice;
double mutation_chance;
double mutation_amount;
double mutation_rate;
int populationSize;
int choice1;
int algorithmChoice;
int choice2;
int HighestTimes[3];
Individual bestData[3];
};
class HillClimberAlgorithm
{
public:
HillClimberAlgorithm ();
HillClimberAlgorithm(int problem, double mutation_chance, double mutation_amount);
myVector <Individual> hillIndividual;
void replace (Individual replacedIndividual);
private:
double fitness;
Individual newIndividualA;
Individual newIndividualB;
};
class GeneticAlgorithm
{
public:
GeneticAlgorithm();
GeneticAlgorithm(int problem, int populationSize, double mutation_rate,double mutation_amount);
int BinarySelection(int populationSize);
void ShowResults();
void Optimize(int problem, int populationSize, double mutation_rate, double mutation_amount);
myVector <Individual> mainVector;
myVector<Individual> results;
void replace(Individual replacedIndividual);
myVector<int>iterations;
int checkAnswer();
private:
int firstRandom;
int secondRandom;
int parentA;
int parentB;
int iterationsNumber;
};
const double PI=3.14159265;
here's the implmentation
#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;
Individual::Individual()
{
}
void Individual::SetProblem(int Problem)
{
problem = Problem;
}
void Individual::SetAlgorithm(int Algorithm)
{
algorithm = Algorithm;
}
void Individual::SetParameters(double mutationChance, double mutationAmount)
{
mutation_chance = mutationChance;
mutation_amount = mutationAmount;
}
int Individual::GetProblem() const
{
return problem;
}
double Individual::GetData(int i) const
{cout <<"im in getdata";
return data[i];
}
int Individual::GetAlgorithm() const
{
return algorithm;
}
void Individual::SetData(int i, double result)
{
data[i]=result;
}
Individual::Individual(int Algorithm, int Problem, double mutationChance, double mutationAmount)
{
SetProblem(Problem);
SetAlgorithm(Algorithm);
SetParameters(mutationChance,mutationAmount);
if (problem==1)
{
for(int i = 0; i < 30; i++)
{
data[i] = static_cast<double>(rand())/ static_cast<double>( RAND_MAX) *(65.536-(-65.536) + 1) + (-65.536);
}
}
if (problem==2)
{
for(int i = 0; i < 30; i++)
{
data[i] = static_cast<double>(rand())/ static_cast<double>( RAND_MAX) *(2.048-(-2.048) + 1) + (-2.048);
}
}
if (problem==3)
{
for(int i = 0; i < 30; i++)
{
data[i] = static_cast<double>(rand())/ static_cast<double>( RAND_MAX) *(600-(-600) + 1) + (-600);
}
}
MathProblemsFitness();
}
Individual::Individual(int Problem)
{
SetProblem(Problem);
if (problem==1)
{
for(int i = 0; i < 30; i++)
{
data[i] = static_cast<double>(rand())/ static_cast<double>( RAND_MAX) *(65.536-(-65.536) + 1) + (-65.536);
}
}
if (problem==2)
{
for(int i = 0; i < 30; i++)
{
data[i] = static_cast<double>(rand())/ static_cast<double>( RAND_MAX) *(2.048-(-2.048) + 1) + (-2.048);
}
}
if (problem==3)
{
for(int i = 0; i < 30; i++)
{
data[i] = static_cast<double>(rand())/ static_cast<double>( RAND_MAX) *(600-(-600) + 1) + (-600);
}
}
MathProblemsFitness();
}
void Individual::MathProblemsFitness()
{
int upperLimit=1;
double holder=0;
double holder1 = 0;
individualFitness=0;
switch(problem)
{
case 1:
{
for(int i = 0; i < 30; i++)
{
holder = 0;
for(int k = 0; k < upperLimit; k++)
{
holder = holder+ data[k];
}
upperLimit++;
individualFitness = individualFitness+ (holder*holder);
}
}
break;
case 2:
{
for(int i = 0; i < 30; 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));
individualFitness= individualFitness + holder;
}
}
case 3:
{
for(int i = 0; i < 30; i++)
{
holder = 0 ;
holder = (data[i]*data[i])/4000;
individualFitness = individualFitness + holder;
}
individualFitness= individualFitness+1;
for(int i = 0; i < 30; i++)
{
holder = 0;
holder = cos(data[i]/sqrt(i+1));
holder1= holder * holder1;
}
individualFitness = individualFitness - holder1;
}
}
}
double Individual::GetFitness() const
{
return individualFitness;
}
//------------------------------------------------------------------------------
HillClimberAlgorithm::HillClimberAlgorithm()
{
}
void HillClimberAlgorithm::replace(Individual newIndividual)
{
double holder =hillIndividual[0].GetFitness();
int index=0;
for(int i = 1; i < hillIndividual.get_size(); i++)
{
if(holder < hillIndividual[i].GetFitness())
{
holder = hillIndividual[i].GetFitness();
index = i;
}
}
for(int i = 0; i < 30; i++)
{
hillIndividual[index].SetData(i,newIndividual.GetData(i));
hillIndividual[index].MathProblemsFitness();
}
}
HillClimberAlgorithm::HillClimberAlgorithm(int problem, double mutation_chance, double mutation_amount)
{
Individual newIndividualA(problem);
fitness= newIndividualA.GetFitness();
while( fitness < .1)
{
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();
if (newFitness < fitness)
{
replace(newIndividualB);
}
iterations++;
}
cout << iterations << endl;
}
}
//------------------------------------------------------------------------------
GeneticAlgorithm::GeneticAlgorithm()
{
}
int GeneticAlgorithm::BinarySelection(int populationSize)
{
firstRandom = static_cast<int>(( static_cast<double>(rand()))/ static_cast<double>( RAND_MAX) *(populationSize-0 + 1) + 0);
secondRandom = static_cast<int>(( static_cast<double>(rand()))/ static_cast<double>( RAND_MAX) *(populationSize-0 + 1) + 0);
}
void GeneticAlgorithm::replace(Individual replacedIndividual)
{
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; //save the index of the individual
}
}
for(int i = 0; i < 30; i++)//over write that individual's data with our child's data
{
mainVector[index].SetData(i,replacedIndividual.GetData(i));
mainVector[index].MathProblemsFitness();
}
iterationsNumber++;
if(iterationsNumber%5 == 0)
{
temp = mainVector[0].GetFitness();
for(int i = 1; i < mainVector.get_size(); i++)
{
if(temp > mainVector[i].GetFitness())
{
temp = mainVector[i].GetFitness();
}
}
cout << "Current Best Fitness: " << temp << endl;
}
}
void GeneticAlgorithm::Optimize(int problem, int population, double mutation_rate, double mutation_amount)
{
parentA=BinarySelection(population);
parentB=BinarySelection(population);
Individual child (problem);
// myVector <Individual>mainVector;
double upperBound=0;
if(problem == 1)
{
upperBound = 131.072;
}
else if(problem == 2)
{
upperBound = 4.096;
}
else
{
upperBound = 1200;
}
for(int i = 0; i < 30; i++)
{
int randomPick = 0;
int selection=0;
selection = static_cast<int>(( static_cast<double>(rand()))/ static_cast<double>( RAND_MAX) *(2-1 + 1) + 1);
if(selection == 1)
{
selection = parentA;
}
else
{
selection = parentB;
}
int mutationChance;
double number=rand() / (double)RAND_MAX;
mutationChance=number < mutation_rate;
if(mutationChance== 1)
{
cout <<"before double";
double newData = mainVector[selection].GetData(i); //heres the error why????
cout <<"im in the optimize";
newData = newData + upperBound*((rand()/ ( RAND_MAX) *(2-0 + 1) + 0)-1)* mutation_amount;
child.SetData(i,newData);
if(newData > (upperBound/2))
{
child.SetData(i,(upperBound/2));
}
else if(newData < ((upperBound/2)*-1))
{
child.SetData(i,((upperBound/2)*-1));
}
}
else
{
child.SetData(i,mainVector[selection].GetData(i));
}
}
child.SetProblem(mainVector[parentA].GetProblem());
child.MathProblemsFitness();
replace(child);
}
int GeneticAlgorithm::checkAnswer()//check to see if the answer is within .1 of the correct answer
{
for(int i = 0; i < mainVector.get_size(); i++)
{
if(mainVector[i].GetFitness() < .1)
{
return 1;
}
else
{
return 0;
}
}
}
GeneticAlgorithm::GeneticAlgorithm (int problem, int populationSize, double mutation_rate, double mutation_amount)
{
UserInterface temporary;
cout << "i'm before the for";
for(int i = 0; i < 10; i++)
{
int counter = 0; //restart the counter
for(int i = 0; i < populationSize; i++)
{
Individual newIndiv(problem); //create a new individual object
mainVector.push_back(newIndiv); //push it into the mainVector
}
int foundIt = 0; //if 0 we haven't found the answer, 1 we have
checkAnswer(); //check to see if we were lucky enough to get the answer in our original population
while(foundIt == 0 && counter < 50) //keep going until we find the answer, or until 5M iterations occur
{
foundIt = checkAnswer(); //check to see if we have an individual with the correct answer
Optimize(problem, populationSize,mutation_rate, mutation_amount); //if not, proceed with breeding and replacing
}
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; //save the index of the individual
}
}
results.push_back(mainVector[index]);
iterations.push_back(counter);
if(problem == 1)
{
if(counter < temporary.GetTimeResult(0))
{
temporary.SetTimeResult(0,counter);
temporary.SetDataResult(0,mainVector[index]);
}
}
else if(problem == 2)
{
if(counter < temporary.GetTimeResult(1))
{
temporary.SetTimeResult(1,counter);
temporary.SetDataResult(1,mainVector[index]);
}
}
else
{
if(counter < temporary.GetTimeResult(2))
{
temporary.SetTimeResult(2,counter);
temporary.SetDataResult(2,mainVector[index]);
}
}
for(int i = 0; i < populationSize; i++) //after the first iteration, clear out the vector
{
mainVector.pop();
}
}
cout << endl;
cout << "Top Individuals" << endl;
cout << "************************************************" << endl;
for(int i = 0; i < results.get_size(); i++)
{
cout << endl;
cout << "Best for individual: ";
cout <<"i'm in the second for";
for(int j = 0; j < 30; j++)
{ cout <<"i'm in the nested for";
cout << results[i].data[j] << " ";
}
cout << endl;
cout << "Fitness Level of Individual : " << results[i].GetFitness() << endl;
cout << "Number of Iterations: " << iterations[i] << endl;
}
for(int i = 0; i < results.get_size(); i++)
{
results.pop();
iterations.pop();
}
cout << endl;
}
//------------------------------------------------------------------------------
UserInterface::UserInterface()
{
}
int UserInterface::GetTimeResult(int index)
{
return HighestTimes[index];
}
void UserInterface::SetTimeResult(int index, int numbers)
{
HighestTimes[index] = numbers;
}
Individual UserInterface::GetDataResult(int index)
{
return bestData[index];
}
void UserInterface::SetDataResult(int index, Individual indiv)
{
bestData[index] = indiv;
}
bool UserInterface::get_number ( int& number )
{
while ( !( cin >> number ) ) {
if ( cin.eof() )
return false;
else {
char ch;
cin.clear();
cout<<"Invalid input, please try again: ";
while (cin.get(ch) && ch != '\n' );
}
}
return true;
}
void UserInterface::MainMenu()
{
menuBool=true;
Individual newIndividual;
for(int i = 0; i < 3; i++)
{
bestData[i] = 5000001;
HighestTimes[i] = 5000001;
}
cout
<<" " <<endl
<<" Function Optimization " << endl;
while (menuBool=true)
{
cout <<"\n"
<< "1) Choose Algorithm (Hill-Climber or Genetic) \n"
<< "2) Choose Algorithm Parameters \n"
<< "3) Choose Problem (Schwefel, Rosenbrock, Griewangk) \n"
<< "4) Perform Opimization \n"
<< "5) Show All Optimization Results \n"
<< "6 Exit \n"
<< "\n";
problemChoice=0;
algorithmChoice=0;
int inputNumber=0;
populationSize=0;
mutation_amount=0;
mutation_chance=0;
mutation_rate=0;
if ( get_number ( inputNumber ) )
switch (inputNumber)
{
case 1:
cout << "Choose Algorithm \n"
<< "1 Hill Climber Algorithm \n"
<< "2 Genetic Algorithm \n";
cin >> algorithmChoice;
if (algorithmChoice==1)
cout << "Hill Climber Algorithm Chosen \n";
else if (algorithmChoice==2)
cout << "Genetic Algorithm Chose \n";
newIndividual.SetAlgorithm(algorithmChoice);
break;
case 2:
algorithmChoice=newIndividual.GetAlgorithm();
if (!algorithmChoice)
cout <<"algorithm not chose\n";
else if (algorithmChoice==1)
{
cout << "enter mutation chance: \n";
cin >> mutation_chance;
cout << "mutation chance: " << mutation_chance <<endl;
cout << "enter mutation amount [0.3-1.0] (enter 3-100): \n";
cin >> mutation_amount;
mutation_amount=mutation_amount/100;
cout <<" mutation amount: " << mutation_amount << endl;
}
else if (algorithmChoice==2)
{
cout << "enter population size [2-50] \n";
cin >> populationSize;
cout <<"population size: " <<populationSize <<endl;
cout <<"enter mutation amonut [.03-1.0](enter 3-100): \n";
cin >> mutation_amount;
mutation_amount=mutation_amount/100;
cout <<"mutation amount: " << mutation_amount << endl;
cout <<"enter mutation rate [.03-.25] (enter 3-25): \n";
cin >> mutation_rate;
mutation_rate=mutation_rate/100;
cout <<"mutation rate: " <<mutation_rate <<endl;
}
break;
case 3:
cout << "Choose Problem \n"
<< "1 Schwefel \n"
<< "2 Rosenbrock \n"
<< "3 Griewangk" << endl;
cin >>problemChoice;
if (problemChoice==1)
cout << "Schwefel Problem Chosen" << endl;
else if (problemChoice==2)
cout << "Rosenbrock Problem Chosen" << endl;
else if (problemChoice==3)
cout << "Griewangk Problem Chosen" <<endl;
newIndividual.SetProblem(problemChoice);
break;
case 4:
{
cin>>problemChoice;
cin>>populationSize;
cin>>mutation_rate;
cin>>mutation_amount;
GeneticAlgorithm(problemChoice,populationSize,mutation_rate, mutation_amount);
}
break;
case 5:
cout <<" Hill Climber Genetic \n"
<<"Schwefel getIterations getIterations\n"
<<"Rosebrock getIterations getIterations\n"
<<"Griegwanzk getIterations getIterations\n";
break;
case 6:
cout << "Exit";
exit(1);
break;
case 7:
{
HillClimberAlgorithm newHillClimber(problemChoice,mutation_amount,mutation_chance);
}
break;
default:
cout <<"Unknow Input\n";
break;
}
menuBool=true;
}
}
and heres the main
#include <iostream>
#include "bpt0004_3.h"
using namespace std;
int main()
{
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(3);
UserInterface newUserInterface;
newUserInterface.MainMenu();
return 0;
}
the error is on line 317 of the implementation and i cannot figure out why its giving me an illegal index?? please i've been trying to figure it out all day