Need assistance with Segmentation Error - c++

The following code is giving me the following error
Error description :
Unhandled exception at 0x00DC5D81 in ImageComponent2.exe: 0xC0000005: Access violation reading location 0xCDCDCDD5.
// ImageComponents
#include <iostream>
#include "Position.h"
using namespace std;
void labelComponents(int size, int **pixel);
void outputImage(int size, int **pixel);
int main(){
int size = 0;
cout << "Enter image size: ";
cin >> size;
int ** pixel = new int *[size + 2];
for (int i = 1; i <= size; i++)
{
pixel[i] = new int[size + 2];
}
cout << "Enter the pixel array in row-major order:\n";
for (int i = 1; i <= size; i++)
for (int j = 1; j <= size; j++)
{
cin >> pixel[i][j];
}
labelComponents(size, pixel);
outputImage(size, pixel);
system("pause");
return (0);
}
void labelComponents(int size, int **pixel){
// initialize offsets
Position * offset = new Position[4];
offset[0] = Position(0, 1); // right
offset[1] = Position(1, 0); // down
offset[2] = Position(0, -1); // left
offset[3] = Position(-1, 0); // up
int numNbr = 4; // neighbors of a pixel position
Position * nbr = new Position(0, 0);
Position * Q = new Position[size * size];
int id = 1; // component id
int x = 0; // (Position Q)
// scan all pixels labeling components
for (int r = 1; r <= size; r++) // row r of image
for (int c = 1; c <= size; c++) // column c of image
{
if (pixel[r][c] == 1)
{// new component
pixel[r][c] = ++id; // get next id
Position * here = new Position(r, c);
do
{// find rest of component
for (int i = 0; i < numNbr; i++)
{// check all neighbors of here
nbr->setRow(here->getRow() + offset[i].getRow());
nbr->setCol(here->getCol() + offset[i].getCol());
if (pixel[nbr->getRow()][nbr->getCol()] == 1)
{// pixel is part of current component
pixel[nbr->getRow()][nbr->getCol()] = id;
Q[x] = *nbr;
x++;
}
}
// any unexplored pixels in component?
*here = Q[x]; // a component pixel
x--;
} while (here != NULL);
} // end of if, for c, and for r
}
} // end of labelComponents
void outputImage(int size, int **pixel){
cout << "The labeled image is: ";
for (int i = 1; i <= size; i++){
cout << endl;
for (int j = 1; j <= size; j++)
cout << pixel[i][j] << " ";
}
} // end of outputImage
//Position.h
#ifndef POSITION_H
#define POSITION_H
class Position
{
private:
int row; // row number of the position
int col;
// column number of the position
public:
Position(); // default
Position( int theRow, int theCol); // parameter
Position(const Position & aPosition); // copy
Position & operator = (const Position & aPosition); // overload =
// overload =
// mutators
void setRow (int r);
void setCol (int c);
//accessors
int getRow() const;
int getCol() const;
}; // end Position
Position::Position()
{
setRow(0);
setCol(0);
}
Position::Position(int r, int c)
{
setRow(r);
setCol(c);
}
Position::Position(const Position & aPosition)
{
setRow(aPosition.row);
setCol(aPosition.col);
}
Position & Position::operator=(const Position & aPosition)
{
this->row=aPosition.row;
this->col=aPosition.col;
return(*this);
}
void Position::setRow(int r)
{
this->row = r;
}
void Position::setCol(int c)
{
this->col = c;
}
int Position::getRow() const
{
return this->row;
}
int Position::getCol() const
{
return this->col;
}
#endif

In C/C++, arraw indexes go from 0 to n-1, not from 1 to n. All your for loops are wrong:
for (int i = 1; i <= size; i++)
Must be replaced by:
for (int i = 0; i < size; i++)
Else, you access array at sizeposition which is out of bound.
Using a debugger and/or working with smaller piece of code would have made it easier for you to figure this out ;-)

Related

C++ find the second shortest path using Dijkstras algorithm?

I have a Dijkstras algorithm program below. My program reads a text file and finds the shortest path from the start node to the goal node. My question is once this shorest path is discovered, given my code, how can I store this path? Reason being I am required to also find the second shorest path. Thankyou
#include <iostream>
#include <fstream>
#include <vector>
#include <limits.h>
#include <stdio.h>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <utility>
using namespace std;
#define INFINITY1 9999
int counter = 0;
int vcount = 0;
int ecount = 0;
int startVertex;
int endVertex;
int nVerticies;
int nEdges;
struct Vertex
{
int label;
int xcord;
int ycord;
};
struct Edge
{
int parent1;
int parent2;
int weight;
};
Vertex *vertArray = NULL;
Edge *edgeArray = NULL;
float distance(int x1, int y1, int x2, int y2)
{
// Calculating distance
return sqrt(pow(x2 - x1, 2) +
pow(y2 - y1, 2) * 1.0);
}
// Dijkstras
void dijkstra(vector<vector<int>> G, int n, int startnode)
{
// Get x and y cords of start node
int startx = vertArray[startnode].xcord;
int starty = vertArray[startnode].ycord;
// Get x and y cords of end node
int endx = vertArray[n].xcord;
int endy = vertArray[n].ycord;
int **cost = new int *[nVerticies];
for (int i = 0; i < nVerticies; ++i)
{
cost[i] = new int[nVerticies];
}
int distance[nVerticies], pred[nVerticies];
int visited[nVerticies], counter, mindistance, nextnode, i, j;
for (i = 0; i < nVerticies; i++)
for (j = 0; j < nVerticies; j++)
// If there is no weight, then set it to infinity
if (G[i][j] == 0)
cost[i][j] = INFINITY1;
else
{
cost[i][j] = G[i][j];
}
for (i = 0; i < nVerticies; i++)
{
distance[i] = cost[startnode][i];
pred[i] = startnode;
visited[i] = 0;
}
distance[startnode] = 0;
visited[startnode] = 1;
counter = 1;
while (counter < nVerticies - 1)
{
mindistance = INFINITY1;
for (i = 0; i < nVerticies; i++)
if (distance[i] < mindistance && !visited[i])
{
mindistance = distance[i];
nextnode = i;
}
visited[nextnode] = 1;
for (i = 0; i < nVerticies; i++)
if (!visited[i])
if (mindistance + cost[nextnode][i] < distance[i])
{
distance[i] = mindistance + cost[nextnode][i];
pred[i] = nextnode;
}
counter++;
}
for(i=n; i<n+1; i++)
if(i!=startnode)
{
cout<<"\nDistance of node "<<i+1<<"="<<distance[i];
cout<<"\nPath="<<i+1;
j=n;
do
{
j=pred[j+1];
cout<<"<-"<<j+1;
}
while(j!=startnode);
}
}
int main()
{
// Declaration for reading file
int a, b, c;
ifstream readFile;
string fileName;
// Ask for file name
cout << "Enter filename: ";
cin >> fileName;
readFile.open(fileName);
// Read last line and set start and goal vertex equal to file input
while (readFile >> startVertex >> endVertex)
{
}
readFile.close();
readFile.open(fileName);
// Read line 1 and set nVerticies and nEdges equal to file input
while (readFile >> nVerticies >> nEdges)
{
counter++;
break;
}
// Create array with size nVerticies
vertArray = new Vertex[nVerticies];
for (int i = 0; i < nVerticies; i++)
{
// Initialise all elements to zero
vertArray[i].label = 0;
vertArray[i].xcord = 0;
vertArray[i].ycord = 0;
}
// Create array with size nEdges
edgeArray = new Edge[nEdges];
for (int i = 0; i < nEdges; i++)
{
// Initialise all elements to zero
edgeArray[i].parent1 = 0;
edgeArray[i].parent2 = 0;
edgeArray[i].weight = 0;
}
vector<vector<int>> G(nVerticies, vector<int>(nVerticies, 0));
while (readFile >> a >> b >> c)
{
// Get vertex from file and add it to array
if (nVerticies >= counter)
{
vertArray[vcount].label = a;
vertArray[vcount].xcord = b;
vertArray[vcount].ycord = c;
vcount++;
counter++;
}
// Get edge from file and add it to array
else
{
G[a - 1][b - 1] = c;
G[b - 1][a - 1] = c;
edgeArray[ecount].parent1 = a;
edgeArray[ecount].parent2 = b;
edgeArray[ecount].weight = c;
ecount++;
counter++;
}
}
readFile.close();
dijkstra(G, endVertex - 1, startVertex - 1);
int n = 11;
int u = 0;
cout << endl;
cout << endl;
cout << endl;
return 0;
}
output from read file
Distance of node 1=46
Path=1<-2
Distance of node 3=65
Path=3<-1<-2
Distance of node 4=47
Path=4<-2
Distance of node 5=36
Path=5<-2
Distance of node 6=53
Path=6<-2
Distance of node 7=135
Path=7<-8<-6<-2
Distance of node 8=99
Path=8<-6<-2
Distance of node 9=95
Path=9<-4<-2
Distance of node 10=82
Path=10<-2
Distance of node 11=116
Path=11<-10<-2
Distance of node 12=76
Path=12<-2
Distance of node 13=85
Path=13<-2
Ive been guided to follow a similar pattern to the following
if you have a path of 1-->2 -->3 -->4
Set 2 to max and try again
Reset 2
Set 3 to max
Reset 3

Dynamic ASCII Box with Numbers Inside

Having a problem in making a dynamic box using these set of ASCII codes. I'm really lost on what to do. This dynamic box also has numbers inside them.
I already tried making loops inside loops to adjust the box's size.
int main(){
char asciis[] = {'\xDA','\xB3','\xC3','\xC0','\x20','\xC4','\xC5','\xC1','\xBF','\xB4','\xD9', '\xC2'};
int box size = (n*2)+1;
char box[box size][box size]; //set the size of the box
//set a in all coordinates
/*for (int r = 0; r < n; r++){
for (int c = 0; c < n; c++){
box[r][c] = 'a';
}
}*/
for (int r = 0; r < n; r++){
for (int c = 0; c < n; c++){
for (int boxrow = 0; boxrow < box size; boxrow++){
for (int boxcol = 0; boxcol < box size; boxcol++){
//conditions
}
}
}
cout << endl;
}
}
This is the output I'm trying to create:
https://i.imgur.com/YRgMlaJ.png
Don't mind those numbers, I was just mapping the array.
I'm sure there's a simpler solution, but off the top of my head:
#include <iostream>
using namespace std;
enum BoxParts {
kLeftUpper = '\xDA',
kVertical = '\xB3',
kLeftBreak = '\xC3',
kLeftLower = '\xC0',
kEmpty = '\x20',
kHorizontal = '\xC4',
kIntersection = '\xC5',
kBottomBreak = '\xC1',
kRightUpper = '\xBF',
kRightBreak = '\xB4',
kRightLower = '\xD9',
kTopBreak = '\xC2',
kCount = 12
};
void drawLine(const int cellCount, const int cellWidth, const char left, const char divider, const char contents, const char right)
{
cout << left;
for (int i = 1; i < cellCount * cellWidth; ++i)
{
if (0 == i % cellWidth)
cout << divider;
else
cout << contents;
}
cout << right << endl;
}
void drawBox(const int cellCount, const int cellWidth, const int cellHeight)
{
// top
drawLine(cellCount, cellWidth, kLeftUpper, kTopBreak, kHorizontal, kRightUpper);
for (int i = 1; i < cellCount * cellHeight; ++i)
{
if (0 == i % cellHeight)
drawLine(cellCount, cellWidth, kLeftBreak, kIntersection, kHorizontal, kRightBreak);
else
drawLine(cellCount, cellWidth, kVertical, kVertical, ' ', kVertical);
}
// bottom
drawLine(cellCount, cellWidth, kLeftLower, kBottomBreak, kHorizontal, kRightLower);
}
int main(int argc, char** argv) {
const int n = 4;
drawBox(n, 10, 5);
getchar();
return 0;
}
Produces:

Segmentation Fault when dealing with 2D Arrays [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I'm am trying to dynamically make 2d arrays that are then supposed to be iterated through to check their contents. Whenever I try to use a function that indexes the array I get a segmentation fault. The two functions that are creating the problems are the printg() and get() functions. I'm not sure exactly what I'm doing wrong, but neither of them will work properly for me.
Any help would be great. Thank you.
#ifndef _GRID_H
#define _GRID_H
#include <iostream>
using namespace std;
class Grid
{
public:
Grid();
Grid(const Grid& g2);
Grid(int x, int y, double density);
Grid(string file);
~Grid();
bool check(int x, int y); //check if a cell is inhabited or not
bool isEmpty();//check if a grid is living
bool equals(const Grid& g2);//checks if two grids are equal
void kill(int x, int y);//kill a cell
void grow(int x, int y);//grow a cell
int getSize();
int getNumRows();
int getNumCol();
int getNumLiving();
void printg(int r, int c);
char get(int x, int y) const;
private:
int size; //number of cells in grid
int row; //row length (number of columns)
int column; //column length (number of rows)
int num_living; //number of X's in the grid
char** myGrid;
};
#endif
#include "Grid.h"
#ifndef _GRID_C
#define _GRID_C
#include <iostream>
#include <cmath>
#include <fstream>
#include <cstdlib>
//compile with g++ -I /home/cpsc350/GameOfLife Grid.cpp
using namespace std;
Grid::Grid() //do i need a default constructor????
{
char myGrid[10][10] = {{0,1,2,3}, {4,5,6,7}, {8,9,10,11}};
row = 10;
column = 10;
size = 100;
}
Grid::Grid(const Grid& g2)//copy constructor/////////////help
{
size = g2.size;
row = g2.row;
column = g2.column;
num_living = g2.num_living;
char** myGrid = new char*[row];
for(int i = 0; i < row; i++)
myGrid[i] = new char[column];
for(int i1 = 0; i1 < row; i1++)
{
for(int i2 = 0; i2 < column; i2++)
{
//copy(&g2[i1][i2], &g2[i1][i2]+row*column,&myGrid[i1][i2]);
myGrid[i1][i2] = g2.get(i1,i2);
}
}
}
Grid::Grid(int x, int y, double density)
{
char** myGrid = new char*[x];
for(int i = 0; i < x; i++)
myGrid[i] = new char[y];
row = x;
column = y;
size = x*y;
num_living = size * density;
string str = "";
for(int a = 0; a < num_living; a++)//adds the density of X's to a string
{
str += 'X';
}
for(int a = 0; a < size - num_living; a++)//adds the rest to the string
{
str += '-';
}
int randnum;
//randomly generates indicies in the string str and puts them into the array
for(int i1 = 0; i1 < column; i1++)
{
for(int i2 = 0; i2 < row; i2++)
{
//generate random numbers from index 0 to length of string - 1
if(str.length()>1)
{
randnum = (rand()%(str.length()-1))+1;
}
else
{
randnum = 0;
}
myGrid[i1][i2] = str[randnum];
str.erase(randnum);
}
}
}
Grid::Grid(string file)
{
num_living = 0;
//code to create a 2d array from a filepath
ifstream openfile(file);
//error handling
if(! openfile)
{
cout << "Error, file could not be opened" << endl;
exit(0);
}
openfile >> column;//gets number of rows
openfile >> row;//gets number of columns
size = row*column;
char** myGrid = new char*[row];
for(int i = 0; i < row; i++)
myGrid[i] = new char[column];
for(int x = 0; x<column; x++)
{
for(int y = 0; y<row; y++)
{
openfile >> myGrid[x][y];
if(! openfile)//error handling
{
cout << "Error reading file at " << row << "," << column << endl;
}
if(myGrid[x][y] == 'X')
{
num_living++;
}
}
}
openfile.close();
}
Grid::~Grid()
{
if(myGrid)
{
for(int i = 0; i < row; i++)
{
delete []myGrid[i];
}
delete []myGrid;
}
}
void Grid::kill(int x, int y)
{
if(myGrid[x][y] == 'X')
{
num_living--;
}
myGrid[x][y] = '-';
}
void Grid::grow(int x, int y)
{
if(myGrid[x][y] == '-')
{
num_living++;
}
myGrid[x][y] = 'X';
}
bool Grid::check(int x, int y)
{
if(y<0 || x<0)
{
return(false);
}
return (myGrid[x][y] == 'X');
}
bool Grid::isEmpty()
{
return (num_living == 0);
}
bool Grid::equals(const Grid& g2)
{
if(size != g2.size) //checks if sizes are equal
{
return false;
}
if(row != g2.row)//checks if numRows are equal
{
return false;
}
if(column != g2.column)//checks if numCol are equal
{
return false;
}
if(num_living != g2.num_living)//checks if numliving are equal
{
return false;
}
for(int x = 0; x < row; x++)//checks each element
{
for(int y = 0; y < column; y++)
{
if(myGrid[x][y] != g2.get(x,y))
{
return false;
}
}
}
return true;
}
int Grid::getSize()
{
return(size);
}
int Grid::getNumRows()
{
return(column);
}
int Grid::getNumCol()
{
return(row);
}
int Grid::getNumLiving()
{
return(num_living);
}
void Grid::printg(int r, int c)
{
for(int x = 0; x < r; x++)
{
for(int y = 0; y < c; y++)
{
cout << myGrid[x][y];
}
cout << endl;
}
}
char Grid::get(int x, int y) const
{
return myGrid[x][y];
}
#endif
The problem that I see at first is that both your default and copy constructor do not initialize myGrid. what you are doing in them will create an additional array with the same name which 'shadows' myGrid. instead you have to do:
Grid::Grid(const Grid& g2)
{
size = g2.size;
row = g2.row;
column = g2.column;
num_living = g2.num_living;
myGrid = new char*[row]; // removed "char**" at the start of this line
for(int i = 0; i < row; i++)
myGrid[i] = new char[column];
for(int i1 = 0; i1 < row; i1++)
{
for(int i2 = 0; i2 < column; i2++)
{
//copy(&g2[i1][i2], &g2[i1][i2]+row*column,&myGrid[i1][i2]);
myGrid[i1][i2] = g2.get(i1,i2);
}
}
}
your default constructor has the same problem. but note that you can't initialize it with braces. but you don't have to have a default constructor if you are not using it.

Adding a random member from an array of chars to a game board in C++

I am programming a game for a university project and i am having a little trouble with it. So here is my game board class header file:
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <cstdio>
#include <time.h>
class CMagicAlchemistBoard
{
public:
CMagicAlchemistBoard(void); // Default Constructor
CMagicAlchemistBoard(const CMagicAlchemistBoard& board); // Copy Constructor
~CMagicAlchemistBoard(void ); // Destructor
void SetupBoard(void); // Function to setup the board
int GetBoardSpace(int row, int col); // Get the color at row,col
// Accessor functions to get/set board size information
int GetColumns(void) const { return m_nColumns; }
void SetColumns(int nColumns) { m_nColumns = (nColumns >= 6) ? nColumns : 6; }
int GetRows(void) const { return m_nRows; }
void SetRows(int nRows) { m_nRows = (nRows >= 8) ? nRows : 8; }
void DeleteBoard(void); // Function to delete the board and free memory
void ExecuteMove(int row, int col);
bool IsGameOver(void) const; // Is the game over?
void DrawBoard(void);
bool ValidMove(int row, int col); // Function to see if a move is valid
char RandomPiece();
private:
void CreateBoard(void); //Function to create the board and allocate memory
// Class Data
int** m_arrBoard; // 2D array pointer
// Board size information
char m_arrChars[20];
int m_nColumns;
int m_nRows;
};
And here are the important parts of the game board .cpp file:
#include "cmagicalchemistboard.h"
using namespace std;
CMagicAlchemistBoard::CMagicAlchemistBoard(void)
: m_arrBoard(NULL), m_nColumns(6), m_nRows(8)
{
m_arrChars[0] = ' ';
}
CMagicAlchemistBoard::CMagicAlchemistBoard(const CMagicAlchemistBoard& board)
{
// Copy all of the regular data members
m_nColumns = board.m_nColumns; m_nRows = board.m_nRows;
m_arrBoard = NULL;
CreateBoard(); // Create a new game board of the same size
// Copy the contents of the game board
for(int row = 0; row < m_nRows; row++)
for(int col = 0; col < m_nColumns; col++)
m_arrBoard[row][col] = board.m_arrBoard[row][col];
int CMagicAlchemistBoard::GetBoardSpace(int row, int col)
{
if(row<0 || row>=m_nRows || col<0 || col>=m_nColumns) return 0;
return m_arrBoard[row][col];
}
void CMagicAlchemistBoard::CreateBoard(void)
{
// If there is already a board, delete it
if(m_arrBoard != NULL) DeleteBoard();
// Create the array of rows
m_arrBoard = new int*[m_nRows];
// Create each row
for(int row = 0; row < m_nRows; row++){
m_arrBoard[row] = new int[m_nColumns];
// Set each square to be empty
for(int col = 0; col < m_nColumns; col++)
m_arrBoard[row][col] = 0;
}
}
void CMagicAlchemistBoard::DrawBoard(void)
{
cout << "MAGIC ALCHEMIST" << endl;
cout << " ";
for(int col = 0; col < m_nColumns; col++){ printf(" ---",col); }
cout << endl;
for(int row = 0; row < m_nRows; row++)
{
for(int col = 0; col < m_nColumns; col++)
{
// printf("| %c", m_arrChars[0]);
cout << "| " << m_arrChars[0];
}
cout << "| " << endl;
}
}
So my idea is to have a function that will add one random char between 12 chars to m_arrBoard[0][2] position. Can someone help me with this please?
Create a function that returns a random character out of 12 predefined
characmters. Call it to assign a random character to m_arrBoard[0][2].
// The function to get a random character.
char getRandomChar()
{
char arr[12] = {}; // Initialize the array of characters.
int index = rand()%12;
return arr[index];
}
Somewhere down in some function....
// Assign a random character to m_arrBoard[0][2].
m_arrBoard[0][2] = getRandomChar();
Let's say you want to receive random characters from A to Z. You can try the following code:
std::vector<char> arr;
int n = (90-65 +1);//'Z'-'A'
int movePosition = 65;
for (unsigned int i = 0; i < 12; ++i)
{
int number = rand() % n;//Get a number from 0 to n-1 (where n is 26)
std::cout << "number = " << number << "; movePosition = " << movePosition << std::endl;
// To get a letter add movePosition to it so you are back in the range of 65 to 90
arr.push_back((char)(number + movePosition));
}
To see what characters you have added, you can try the following:
for (int i = 0;i<arr.size();i++)
{
std::cout << "Char=" << arr[i] << std::endl;
}

2D vector class variable for a genetic algorithm gives a bad_alloc error

I'm writing a genetic algorithm for which I'm creating a "crossover" operator as a class object that is passed the two parent "chromosomes" Because the input and therefore the output chromosomes are variable lengths, my idea was two divide the input chromosomes and place in a sort of storage class variable, then resize the input chromosomes, and then finally refill the input chromosomes. I'm getting a bad_alloc error, however. If someone could spot my error I'd very much appreciate the help.
Thanks! My class code is below. Note that "plan_vector" is a 2d vector of int types.
#include <iostream>
#include <vector>
#include <eo>
class wetland_vector : public std::vector<int> {
public:
wetland_vector() : std::vector<int>(1, 0) {
}
};
std::istream& operator>>(std::istream& is, wetland_vector& q) {
for (unsigned int i = 0, n = 1; i < q.size(); ++i) {
is >> q[i];
}
return is;
}
std::ostream& operator<<(std::ostream& os, const wetland_vector& q) {
os << q[0];
for (unsigned int i = 1, n = 1; i < q.size(); ++i) {
os << " " << q[i];
}
os << " ";
return os;
}
class wetland_vector_Init : public eoInit<wetland_vector> {
public:
void operator()(wetland_vector& q) {
for (unsigned int i = 0, n = q.size(); i < n; ++i) {
q[i] = rng.random(10);
}
}
};
class plan_vector : public eoVector<double, wetland_vector> {
};
int read_plan_vector(plan_vector _plan_vector) {
for (unsigned i = 0; i < _plan_vector.size(); i++) {
//Call function that reads Quad[1]
//Call function that reads Quad[2]
//etc
return 0;
}
return 0;
};
class eoMutate : public eoMonOp<plan_vector> {
int subbasin_id_min;
int subbasin_id_max;
int wetland_id_min;
int wetland_id_max;
bool operator() (plan_vector& _plan_vector) {
//decide which Quad to mutate
int mutate_quad_ID = rng.random(_plan_vector.size());
//decide which Gene in Quad to mutate
int mutate_gene_ID = rng.random(_plan_vector[mutate_quad_ID].size());
//mutation procedure if first slot in the Quad is selected for mutation
if (mutate_quad_ID = 0) {
_plan_vector[mutate_quad_ID][mutate_gene_ID] = rng.random(subbasin_id_max);
}
//mutation procedure if second slot in the Quad is selected for mutation
if (mutate_quad_ID = 1) {
_plan_vector[mutate_quad_ID][mutate_gene_ID] = rng.random(subbasin_id_max);
}
//note: you'll need to add more for additional wetland characteristics
return true;
};
public:
void set_bounds(int, int, int, int);
};
void eoMutate::set_bounds(int a, int b, int c, int d) {
subbasin_id_min = a;
subbasin_id_max = b;
wetland_id_min = c;
wetland_id_max = d;
}
double evaluate(const plan_vector& _plan_vector) {
int count = 0;
for (int i = 0; i < _plan_vector.size(); i++) {
for (int j = 0; j < _plan_vector[i].size(); j++) {
count += _plan_vector[i][j];
}
}
return (count);
}
class eoQuadCross : public eoQuadOp<plan_vector> {
public:
std::string className() const {
return "eoQuadCross";
}
plan_vector a1;
plan_vector a2;
plan_vector b1;
plan_vector b2;
bool operator() (plan_vector& a, plan_vector& b) {
int cross_position_a = rng.random(a.size() - 1);
int cross_position_b = rng.random(b.size() - 1);
for (int i = 0; i < cross_position_a; i++) {
a1.push_back(a[i]);
}
for (int i = cross_position_a; i < a.size(); i++) {
a2.push_back(a[i]);
}
for (int i = 0; i < cross_position_b; i++) {
b1.push_back(b[i]);
}
for (int i = cross_position_b; i < b.size(); i++) {
b2.push_back(b[i]);
}
int size_a = b2.size() + a1.size();
int size_b = a2.size() + b1.size();
a.resize(size_a);
b.resize(size_b);
for (int i = 0; i < b2.size(); i++) {
a.push_back(b2[i]);
}
for (int i = 0; i < a1.size(); i++) {
a.push_back(a1[i]);
}
for (int i = 0; i < a2.size(); i++) {
b.push_back(a2[i]);
}
for (int i = 0; i < b1.size(); i++) {
b.push_back(b1[i]);
};
//Return bool
return true;
}
};
int main() {
unsigned int vec_size_min = 1;
unsigned int vec_size_max = 10;
unsigned int pop_size = 100;
//BEGIN COPY PARAMETRES
const unsigned int MAX_GEN = 100;
const unsigned int MIN_GEN = 5;
const unsigned int STEADY_GEN = 50;
const float P_CROSS = 0.8;
const float P_MUT = 0.5;
const double EPSILON = 0.01;
double SIGMA = 0.3;
const double uniformMutRate = 0.5;
const double detMutRate = 0.5;
const double normalMutRate = 0.5;
//END COPY PARAMETERS
rng.reseed(1);
//Create population
wetland_vector_Init atom_init;
eoInitVariableLength<plan_vector> vec_init(vec_size_min, vec_size_max, atom_init);
eoPop<plan_vector> pop(pop_size, vec_init);
//Create variation operators
eoMutate mutate;
mutate.set_bounds(1, 453, 1, 4);
eoQuadCross crossover;
eoDetTournamentSelect<plan_vector> select(3);
eoSGATransform<plan_vector> transform(crossover, .5, mutate, .2);
//Create fitness function
eoEvalFuncPtr<plan_vector> eval(evaluate);
//Evaluate initial population and cout
apply<plan_vector > (eval, pop);
std::cout << pop << std::endl;
//Set GA for execution and execute
eoGenContinue<plan_vector> GenCount(5);
eoSGA<plan_vector> gga(select, crossover, .5, mutate, .1, eval, GenCount);
gga(pop);
//cout final population and end
std::cout << pop << std::endl;
std::cout << "The End" << std::endl;
}
a1.~vector();
a2.~vector();
b1.~vector();
b2.~vector();
You shall not destruct the vectors manually, otherwise the next time you try to access them (upon next call to the operator ()) you get undefined behavior.
Why do you call vector destructor manually?? You should let C++ call that for you. If you want to clear the vector use clear member function