Crossover in genetic algorithm - c++

The part where I get an error (more specifically, where I get a popup saying Debug error! Abort () has been called) is the part where I try to do a crossover.
for (int i = 0; i < number_of_variables; i++)
{
int gene1 = gene_selection(rng);
std::cout << gene1 << " ";
if (gene1 == 0)
{
std::cout << "test 0";
new_individuals[k].chromosomes[0].at(i) = individuals[father].chromosomes[0].at(i);
}
else if (gene1 == 1)
{
std::cout << "test 1";
new_individuals[k].chromosomes[0].at(i) = individuals[mother].chromosomes[0].at(i);
}
}
It gets far enough to display "test 0" or "test 1" but it won't actually assign the genes from the father/mother to the new_individual.
I've tried changing up the line where it assigns the old genes to the new individual, but regardless of what I try I can't get it working.
If anyone could show me where (or how) I'm messing up, I'd be very thankful :)
Edit: Stepping through the debugger, I get the following
http://prnt.sc/b0iprq
Unhandled exception at .... in LearnCPP.exe: Microsoft C++ exception: std::out_of_range at memory location .....
Another edit: Just to be clear, it's this exact line where the abort occurs:
new_individuals[k].chromosomes[0].at(i) = individuals[father].chromosomes[0].at(i);

I'm surprised you get "test0" or "test1", without a std::endl
Follow the story of new_individuals
You allocate and resize it with
std::vector<one_individual> new_individuals;
new_individuals.resize(population_size);
Next this resize(), you have a vector of population_size (5) one_individual elements where chromosomes are std::vector<std::vector<double>> of size 0.
Next you resize the chromosomes with
for (int i = 0; i < population_size; i++)
{
new_individuals[i].chromosomes.resize(number_of_variables);
}
At this point you have cromosomes of size number_of_variables (7) but what's the meaning of this?
It's mean than every cromosomes is an std::vector of seven std::vector<double> of size zero.
So, when you access
new_individuals[k].chromosomes[0].at(i)
with k == 1 (why 1 and not 0?) and i == 0, new_individual[1].chromosomes[0] exist but is of size 0, new_individuals[k].chromosomes[0].at(i) check the size of chromomoses[0] to see if at least 1, fail and cause an exception (std::out_of_range)
Your intention was to allocate every new_individuals[i].chromosomes[j]?
Or your intention was to write
new_individuals[k].chromosomes[0].push_back(individuals[father].chromosomes[0].at(i));
?
p.s.: sorry for my bad English.
--- EDIT---
If your intention is to reserve 7x7 chromosomes, one way can be
for (int i = 0; i < population_size; i++)
{
new_individuals[i].chromosomes.resize(number_of_variables);
for (int j = 0; j < population_size; j++)
new_individuals[i].chromosomes[j].resize(number_of_variables);
}
Even using push_back(), I suggest you to reserve space
for (int i = 0; i < population_size; i++)
{
new_individuals[i].chromosomes.resize(number_of_variables);
for (int j = 0; j < population_size; j++)
new_individuals[i].chromosomes[j].reserve(number_of_variables);
}

Related

Stack overflow when manipulating Bi-dimensional integer array

I wrote this C++ program to sort an integer matrix using selection sort. I tried to compile and run the program. But I ran into a stack overflow error and the message also said something about an access violation writing location .
I tried the following steps:
Tried reducing the array size from 50 x 50 to 10 x 10.
Tried heap allocation to the resultant array (using new).
Tried declaring the resultant array as static.
Tried examining the Memory option in Debug Menu for that particular memory
location(but couldn't make sense of it).
Tried examining the chkstk.asm file that the IDE automatically opened.
But all these efforts were of no use.
This is the part of the source code involved in the runtime error.
void SelectionSort(int matrix[][10], int rowMax, int colMax)
{
//Runtime error was pointed over here.
int smallest, temp, position, count = 0;
int resultant[10][10];
for (int row = 0; row < rowMax; row++)
{
for (int j = 0; j < rowMax - 1; j++)
{
smallest = matrix[row][j];
position = j;
for (int k = j + 1; k < rowMax; k++)
{
if (matrix[row][k] < smallest)
{
smallest = matrix[row][k];
position = k;
}
}
temp = matrix[row][j];
matrix[row][j] = matrix[row][position];
matrix[row][position] = temp;
}
}
for (int i = 0; i < rowMax; i++)
for (int j = 0; j < colMax; j++)
resultant[i][j] = matrix[j][i];
if (count == 0)
{
SelectionSort(resultant, rowMax, colMax);
count++;
}
else
{
std::cout << "The sorted matrix is: " << std::endl;
for (int i = 0; i < rowMax; i++)
{
for (int j = 0; j < colMax; j++)
{
std::cout << matrix[i][j] << " ";
}
std::cout << "\n";
}
}
}
These were the messages that were thrown.
Exception thrown at 0x00007FF79D763488 in Sorting Algorithm Benchmarking Program.exe: 0xC0000005: Access violation writing location 0x000000BFBF600000. occurred
and
Unhandled exception at 0x00007FF79D763488 in Sorting Algorithm Benchmarking Program.exe: 0xC00000FD: Stack overflow (parameters: 0x0000000000000001, 0x00000058CE0B3000). occurred
I expected the sorted matrix to be printed in the console.
For example, if the unsorted matrix is:
1 9 5
8 3 6
7 4 2
then the output should be:
1 2 3
4 5 6
7 8 9
I would request you not to send complicated template-based suggestions, as I am in the intermediate level of C++ programming.
Thanks in advance!

How to Compare multiple variables at the same time in the C++?

I'm making Sudoku validater program that checks whether solved sudoku is correct or not, In that program i need to compare multiple variables together to check whether they are equal or not...
I have provided a snippet of code, what i have tried, whether every su[][] has different value or not. I'm not getting expecting result...
I want to make sure that all the values in su[][] are unequal.
How can i achieve the same, what are mistakes in my snippet?
Thanks...
for(int i=0 ; i<9 ;++i){ //for checking a entire row
if(!(su[i][0]!=su[i][1]!=su[i][2]!=su[i][3]!=su[i][4]!=su[i][5]!=su[i][6]!=su[i][7]!=su[i][8])){
system("cls");
cout<<"SUDOKU'S SOLUTION IS INCORRECT!!";
exit(0);
}
}
To check for each column uniqueness like that you would have to compare each element to the other ones in a column.
e.g.:
for (int i = 0; i < 9; ++i) {
for (int j = 0; j < 9; ++j) {
for (int k = j + 1; k < 9; ++k) {
if (su[i][j] == su[i][k]) {
system("cls");
cout << "SUDOKU'S SOLUTION IS INCORRECT!!\n";
exit(0);
}
}
}
}
Since there are only 8 elements per row this cubic solution shouldn't give you much overhead.
If you had a higher number N of elements you could initialize an array of size N with 0 and transverse the column. For the i-th element in the column you add 1 to that elements position in the array. Then transverse the array. If there's a position whose value is different from 1, it means you have a duplicated value in the column.
e.g.:
for (int i = 0; i < N; ++i) {
int arr[N] = {0};
for (int j = 0; j < N; ++j)
++arr[su[i][j] - 1];
for (int i = 0; i < N; ++i) {
if (arr[i] != 1) {
system("cls");
cout << "SUDOKU'S SOLUTION IS INCORRECT!!\n";
exit(0);
}
}
}
This approach is way more faster than the first one for high values of N.
The codes above check the uniqueness for each column, you would still have to check for each row.
PS: I have not tested the codes, it may have a bug, but hope you get the idea.

adjacency list error with list

Basically i generated a adj_matrix and i want to make an adj_list from the adj_matrix...However I keep getting an error saying "no match for call..."
i tried it without aPair i still get the same error i can't seem to figure out what my problem is. Can anyone tell me why list isn't working? the list is at the very end of the code
int **gen_random_graph(int n)
{
srand(time(0));
int **adj_matrix = new int*[n];
for(int i = 0; i < n; i++)
{
for (int j = i; j < n; j++) //generating a N x N matrix based on the # of vertex input
{
adj_matrix[i] = new int[n];
}
}
for(int u = 0; u < n; u++)
{
for (int v = u; v < n; v++)
{
bool edgeOrNot = rand() % 2; //decide whether it has an edge or not
adj_matrix[u][v] = adj_matrix[v][u] = edgeOrNot;
if(adj_matrix[u][v] == true)
{
adj_matrix[v][u] = true;
if(u == v) //We can't have i = j in an undirected graph so we set it to false
{
adj_matrix[u][v] = -1;
}
}
else //if adj_matrix[u][v] is false set the symmetry to be false
{
adj_matrix[v][u] = adj_matrix[u][v] = -1;
}
}
}
for(int i = 0; i < n; i++)
{
for(int j = i; j < n; j++) //create the N x N with edges and sets the weight between the edge randomly
{
if(adj_matrix[i][j] == true)
{
int weight = rand() % 10 + 1;
adj_matrix[i][j] = adj_matrix[j][i] = weight;
cout << " ( " << i << "," << j << " ) " << "weight: " << adj_matrix[i][j] << endl;
}
}
}
for(int i = 0; i < n; i++)
{
vector<int> adj_list;
for(int j = i; j < n; j++)
{
if(adj_matrix[i][j] > 0)
{
int weight = adj_matrix[i][j];
adj_list.push_back(j);
cout << adj_list[i] << " " << endl;
}
}
}
print(n,adj_matrix);
return (adj_matrix);
}
I see that adj_list is not callable, so your code there is broken. There are a couple simple solutions to that. Taking a look at these docs, you may simply either access listObj.front() and listObj.back() OR you may also just create an iterator using listObj.begin() and iterating over the two elements (which may be desirable if you ever decide to put more than two elements in the list). See this tutorial for a simple example on creating an iterator for a list, in the code snippet right above the summary.
Note, here, your list object which I called listObj for simplicity/abstraction would simply be adj_matrix[i][j] in that bottom loop. That should fix your syntax error.
Also, aside from the syntax of your code, I don't get why you're trying to push weights to a list, then you're printing out and returning the adjacency matrix. I also don't get why you would use lists of pair objects when it seems like you only want to push integer weights onto it. For that, you can use a simple vector of integers (i.e.: vector <int> adj_list;)... or even simpler, you could use a simple array of integers... rather than using a vector of lists of pairs.
EDIT: After running the code locally and taking a look at the values, I realized the issue a bug in the OP's output was simply that he was using "true" in C++ in place of an integer, which was creating a bug, as explained in this SO post. The OP also has a further design decision to make where adjacency lists are concerned. More on what an adjacency list is, conceptually, found on Wikipedia.

Noobish Array problems: Run-Time Check Failure #2 - Stack around the variable 'arr' was corrupted

I'll be pretty honest/upfront here- I'm both a noob to C++, to computer programming in general, and additionally, to this site as well. I'll just preface my question by saying that I did in fact look at other questions possibly related to my own, but it just felt like they were outside of my scope. With that said, here's my problem:
I get this error message:
"Run-Time Check Failure #2 - Stack around the variable 'arr' was corrupted."
Here's my code. It's just a basic little thing for some array practice. The function multiTable outputs a multiplication table:
#include <iostream>
#include <iomanip>
using namespace std;
void multiTable();
int main()
{
multiTable();
return 0;
}
//Prints a 9 by 9 multiplication table;
void multiTable()
{
const int row = 9, col = 9;
int arr[row][col];
for(int i = 1; i <= row; i++)
{
for(int j = 1; j <= col; j++)
{
arr[i][j] = j * i;
cout << setw(3);
cout << arr[i][j];
}
cout << endl;
}
}
I also want to mention that instead of the function call, had I just included all of the code contained within the function body in main, I don't get the run-time error. Why is it that when it's contained within a function, I get the runtime error, but when it's just in main, I don't get the error? And of course, what would I have to change in order for the function call to not produce the error?
Those are your problems: for(int i = 1; i <= row; i++) and for(int j = 1; j <= col; j++) array counting starts from 0. So your for loops should be like this (starting from 0 and omitting the = part from <=):
for(int i = 0; i < row; i++) and for(int j = 0; j < col; j++)

Segmentation fault with multidimensional arrays

I tried searching through this website for possible answers of why this error is occurring but couldn't find the exact answer.
For this little code, I basically have the program read input from a file. (It reads every single character.) Then store it in a multi-dimensional array (2D) and finally print out the array.
This is my code:
ifstream file;
char gamemap[20][26];
file.open("maze-hard.txt");
if(!file.is_open())
{
cout << "Error: Cannot open file" << endl;
return 0;
}
for(int i = 0; i < 20; i++)
{
for(int j = 0; j < 26; i++)
{
gamemap[i][j] = file.get();
cout << gamemap[i][j];
}
cout << endl;
}
It was somewhat successful, but I got a segmentation fault error. I don't know where the problem lies. Don't go hard on me for this one. I'm not all that advanced in C++.
for(int j = 0; j < 26; i++)
I'd replace that i++ with a j++.
increment j in the second cycle, not i ;)
While probably not strictly related to this particular segfault, I'd also check to make sure that the read is good for safety.
if(file.good())
{
gamemap[i][j] = file.get();
//etc etc
}