I've been trying to write a code for two point crossover operation in a genetic algorithm. At first two random gene location is selected. After that, two chromosomes swap their genes which are located btw random numbers called genelocation1 and genelocatıon2.
for example First Gene [0.3,0.2,0.4,0,0.1,0.5,0.7]
Second Gene [0.25,0.6,0.45,0.15,0.80,0.9,0.85]
rndm genelocation1=3
rdnm gnelocation2 =5
child Gene1 [0.3,0.2,0.4,0.15,0.80,0.5,0.7]
Gene2 [0.25, 0.6, 0.45, 0, 0.1,0.9,0.85]
my problem is this: since two numbers are generated randomly, i could not define an array like array[genelocation2-genelocation1].. How can i solve the problem. here is my whole code about two point crossover. pointers maybe a solution but i am not good at pointers.
Here is the code:
void Xover (int mother,int father)
{
int tempo;
int Rndmgenelocation1=(rand()%ActivityNumber);
int Rndmgenelocation2=(rand()%ActivityNumber);
if (Rndmgenelocation1>Rndmgenelocation2)//sure that 2>1
{
tempo=Rndmgenelocation1;
Rndmgenelocation1=Rndmgenelocation2;
Rndmgenelocation2=tempo;
}
int size=(Rndmgenelocation2-Rndmgenelocation1);
int Temp1[size];//this makes an error
int ppp=Rndmgenelocation1;
for (int pp=Rndmgenelocation1;pp<Rndmgenelocation2;pp++)
{
Temp1[pp]=Sol_list[father].Chromosome[ppp];
ppp++;
}
int pppx=Rndmgenelocation1;
for (int ppx=Rndmgenelocation1;ppx<Rndmgenelocation2;ppx++)
{
Sol_list[father].Chromosome[ppx]=Sol_list[mother].Chromosome[pppx];
pppx++;
}
int ppplx=Rndmgenelocation1;
for (int pplx=Rndmgenelocation1;pplx<Rndmgenelocation2;pplx++)
{
Sol_list[father].Chromosome[pplx]=Temp1[ppplx];
ppplx++;
}
return;
}
You can't define an array of variable size on the stack.
You could use
int *Temp1=new int[size]
You then must not forget to call
delete[] Temp1;
at the end of your function!
edit:
I didn't test my code below, but the following should do what you want in a more efficient (and more understandable) way:
#include <algorithm>
void Xover (int mother,int father)
{
int Rndmgenelocation1=(rand()%ActivityNumber);
int Rndmgenelocation2=(rand()%ActivityNumber);
if (Rndmgenelocation1>Rndmgenelocation2)//sure that 2>1
{
std::swap(Rndmgenelocation1,Rndmgenelocation2);
}
for (int pp=Rndmgenelocation1;pp<Rndmgenelocation2;pp++)
{
std::swap(Sol_list[father].Chromosome[pp],Sol_list[mother].Chromosome[pp]);
}
return;
}
edit2:
I just found here another even better way - the STL implements a ready-to-use cross over algorithm. Use:
#include <algorithm>
void Xover (int mother,int father)
{
int Rndmgenelocation1=(rand()%ActivityNumber);
int Rndmgenelocation2=(rand()%ActivityNumber);
if (Rndmgenelocation1>Rndmgenelocation2)//sure that 2>1
{
std::swap(Rndmgenelocation1,Rndmgenelocation2);
}
std::swap_ranges(
Sol_list[father].Chromosome[Rndmgenelocation1],
Sol_list[father].Chromosome[Rndmgenelocation2],
Sol_list[mother].Chromosome[Rndmgenelocation1]
);
return;
}
I'm guessing you must not be using g++ as your compiler. If so, you can use a std::vector rather than an array. Simply do
std::vector<int> array(size);
Now you can treat it like a "normal" array though the operator[] syntax. There's also no concern about memory leaks from forgetting to call delete on a pointer.
Related
I have just coded while on the train this, that creates a vector of objects.
I would appreciate if someone has a suggestion to make it more elegant or effective?
#include <iostream>
#include <vector>
using namespace std;
typedef struct{
short xpos,ypos;
short width, height;
short area;
}LABELPROP;
int get_property(int n,LABELPROP *pP)
{
if(n%2)
{
pP->xpos=n*2;
pP->ypos=n*3;
return 1;
}
else return 0;
}
int main()
{
vector<LABELPROP> myvector;
cout<<"Initial Number :"<<myvector.size()<<endl;
LABELPROP temporal;
// LABELPROP *pT=&temporal;
for(int n=1;n<=10;n++) //10 objects
{
//if(get_property(n,pT))
if(get_property(n,&temporal))
myvector.push_back(temporal);
}
for(int i=0;i<myvector.size();i++)
cout<<"("<<myvector[i].xpos<<","<<myvector[i].ypos<<")"<<endl;
return 0;
}
As you can see I eliminated an unnecessary pointer that I originally put.
the temporal struct gets its values from the get_property function so that is why I put that as a pointer
Thanks in advance
You are writing C++ in a C style. You don't need to typedef your struct, just use:
struct LabelProp
{
LabelProp(short xpos, short ypos) : xpos(xpos), ypos(ypos) {}
short xpos,ypos;
short width, height;
short area;
};
I also changed the naming, because most conventions use all uppercase names as constants or macros. I also added a constructor to be used.
You have get_property returning an int, but since this is c++, return a bool.
Probably an even better idea would be replace get_property with addIfOdd and have it look something like:
void addIfOdd(int n, std::vector<LabelProp>& results)
{
if(n%2)
{
results.emplace_back(n * 2, n * 3);
}
}
int main()
{
std::vector<LabelProp> myvector;
for(int n=1;n<=10;n++) //10 objects
{
addIfOdd(n, myvector);
}
}
It looks like you are unnecessarily iterating over a full range of integers when it is in fact the odd numbers that you're after. Why not limit the range to odd numbers? (only half as many iterations), e.g.:
for(int i = 1; i < 10; i += 2) { /* 1, 3, ..., 9 */ }
Using modern C++ you could add a constructor to your class:
explicit label_prop(int n)
: xpos{static_cast<short>(n * 2)}, ypos{static_cast<short>(n * 3)} {}
and replace all your code with a std::generate_n, e.g.:
std::generate_n(std::back_inserter(myvector), 5, [n = 1] () mutable {
return label_prop{std::exchange(n, n + 2)};
});
Here, you're specifying that you want 5 consecutive odd numbers, starting at 1.
If your compiler is modern enough and supports C++11 features, you could use the new range-based for loop, like this:
for(auto& x : myvector)
cout<<"("<<x.xpos<<","<<x.ypos<<")"<<endl;
Also, in order to improve the eficiency you can use the reserve method if you know in advance the size of the vector, so that you can avoid unnecessary object reallocations and memory allocations/deallocations, which can be expensive.
I'm struggling with a random exception when using std::vector.
Here are the main elements :
struct Stroke
{
std::vector<vec2> points;
Pixel color;
std::vector<unsigned int> pixelIds;
};
void myFunc()
{
while (strokes.size() < 5000)
{
if (/*A condition that is always met at some point*/)
{
break;
}
//Some code
newStroke->pixelIds.clear();
newStroke->pixelIds.resize(0);
strokes.push_back(newStroke);
}
for (int i = 0; i < strokes.size(); ++i)
{
drawStroke(strokes[i]);
}
}
void drawStroke(Stroke * currentStroke)
{
std::vector<int> roundIds;
//Fill roundIds
//Some loops and conditions
for (int i = 0; i < roundIds.size(); ++i)
{
if (/*Check condition*/)
{
// Exception is raised deeper in the stack here
currentStroke->pixelIds.push_back(currentRoundId);
}
}
}
I left out big parts of the code that shouldn't really affect this because I have no idea where the problem could come from (so I'd have to copy/paste the whole code :D). In the last line I randomly get an Access violation deeper in the stack (_Orphan_Range method of std::vector).
I don't see anything wrong with currentStroke in the watch, the points vector is looking normal, color too, I guess that some internal values of pixelIds are broken (_Myfirst=0x000000000038c700 _MyEnd=0x000000000038c74c doesn't look too good to me but I'm not sure).
I'm not very experienced with the details of STL and I don't know what to look for especially since the vector is only holding unsigned int values, not some fancy weird class or structure and I have no idea what could ever mess up with the internal values of a vector.
Any suggestion or advice will be appreciated!
Thanks!
myFunct has an endless loop that fills stoke vector until you get out of memory.
when i am trying to run this code for input 1 and 1000 it shows me segmentation fault .what will be the correction in this code ?
void sorting(int sum[],long int k);
int main() {
int sum[100000];
int L,R,i,j;
long int k=0;
cin>>L;
cin>>R;
for(i=L;i<=R;i++)
{
for(j=i;j<=R;j++)
{
sum[k]=i^j;
k++;
}
}
sorting(sum,k);
cout<<sum[k-1];
return 0;
}
void sorting(int sum[],long int k)
{
int i,j;
long int temp;
for(i=0;i<k;i++)
{
for(j=0;j<k;j++)
{
if(sum[i]<=sum[j])
{
temp=sum[i];
sum[i]=sum[j];
sum[j]=temp;
}
}
}
}
The segmentation fault is caused by stack overflow. This line:
int sum[100000];
sum uses 400K spaces of stack, which is bigger than the normal size of stack.
To fix the problem, you can use std::vector to implement sum instead.
I think the problem is not in the stack size, but content of variable k
for(i=L;i<=R;i++)
{
for(j=i;j<=R;j++)
{
sum[k]=i^j;
k++;
}
}
For L = 1, R = 1000, this loop makes k as large as 500500, which exceeds the size of sum array, which has 100000 elements.
To dirty-fix this error you could make sum array larger, but, since stack size indeed can be limited, it's better to allocate huge arrays on a heap. This is also more elegant solution in your case, because you can dynamically set required size of the array.
To allocate memory on heap you can use std::vector or C++11 unique_ptr<int[]> (you could also use new[] and delete[], although recently it is advised to use methods mentioned previously, because they secure some aspects of dynamic memory allocation).
To create array with unique_ptr<int[]>
std::unique_ptr<int[]> sum = std::make_unique<int[]>(mysize);
//or if make_unique is not available
std::unique_ptr<int[]> sum(new int[mysize]);
It looks like you have arithmetic series, so you can calculate mysize using equations for the sum of arithmetic progression http://en.wikipedia.org/wiki/Arithmetic_progression#Sum
With std::vector it can be less error-prone, because std::vector can grow, so you can simply push_back() elements inside the loop.
Define sum variable
std::vector<int> sum;
Then inside the loop instead of sum[k]=i^j; you write
sum.push_back(i^j);
I just implemented breadth first search in c++ and instead of declaring a vector as bool, I declared it as an int. This lead to a very odd observation. When I used int, the code printed the following:
1
32763
-524268732
Throughout the entire code, I don't provide any such value to variable as the 2nd and 3rd node receive, so I assume that they are just garbage values, but why do garbage values even come up, when I'm initialising the vector to be full of zeroes ??? You may check the code to be that below:
#include <iostream>
#include <queue>
using namespace std;
queue<int> neigh;
vector< vector<int> > graph(3);
vector<int> flag(3, 0);
int main(void)
{
graph[0].push_back(1); graph[0].push_back(2);
graph[1].push_back(0); graph[1].push_back(2);
graph[2].push_back(0); graph[3].push_back(1);
neigh.push(0);
while(!neigh.empty())
{
int cur = neigh.front();
neigh.pop();
flag[cur] = 1;
for(int i = 0, l = graph[cur].size();i < l;i++)
{
if(!flag[graph[cur][i]])
neigh.push(graph[cur][i]);
}
}
for(int i = 0;i < 3;i++)
{
cout << flag[i] << endl;
}
}
Alright, then I changed just a single line of code, line number 7, the one where I declare and initialise the flag vector.
Before:
vector<int> flag(3, 0);
After:
vector<bool> flag(3, false);
And voila! The code started working:
1 //The new output
1
1
So, my question is, what is the problem with the code in the first place ? I believe it may be some kind of error I made, or possibly that its only by chance that my bfs implementation works at all... So, what is the truth, SO? What is my (possible) mistake ?
You are accessing your vector out of bounds here:
graph[3].push_back(1);
At this moment, graph only has three elements. This leads to undefined behaviour.
as the title explains this is a program to find lcm of numbers between 1 to 20. i found an algorithm to do this, here's the link
http://www.cut-the-knot.org/Curriculum/Arithmetic/LCM.shtml
there is a java applet on the webpage that might explain the algorithm better
Problem: i wrote the code compiler shows no error but when i run the code the program goes berserk, i guess may be some infinite loopig but i can't figure it out for the life of me. i use turbo c++ 4.5 so basically if anyone can look at the code and help me out it would be great . thanks in advance
Algorithm:
say we need to find lcm of 2,6,8
first we find the least of the series and add to it the number above it, i.e the series become
4,6,8
now we find the least value again and add to it the intitial value in the column i.e 2
6,6,8
so the next iteration becomes
8,6,8
8,12,8
10,12,8
10,12,16
12,12,16
14,12,16
14,18,16
16,18,16
18,18,16
18,18,24
20,18,24
20,24,24
22,24,24
24,24,24
as you can see at one point all numbers become equal which is our lcm
#include<iostream.h>
/*function to check if all the elements of an array are equal*/
int equl(int a[20], int n)
{
int i=0;
while(n==1&&i<20)
{
if (a[i]==a[i+1])
n=1;
else
n=0;
i++;
}
return n;
}
/*function to calculate lcm and return that value to main function*/
int lcm()
{
int i,k,j,check=1,a[20],b[20];
/*loading both arrays with numbers from 1 to 20*/
for(i=0;i<20;i++)
{
a[i]=i+1;
b[i]=i+1;
}
check= equl(a,1);
/*actual implementation of the algorith*/
while(check==0)
{
k=a[0]; /*looks for the least value in the array*/
for(i=0;i<20;i++)
{
if(a[i+1]<k)
{
k=a[i+1]; /*find the least value*/
j=i+1; /*mark the position in array */
}
else
continue;
}
a[j]=k+b[j]; /*adding the least value with its corresponding number*/
check= equl(a,1);
}
return (a[0]);
/*at this point all numbers in the array must be same thus any value gives us the lcm*/
}
void main()
{
int l;
l=lcm();
cout<<l;
}
In this line:
a[j]=k+b[j];
You use j but it is unitialized so it's some huge value and you are outside of the array bounds and thus you get a segmentation fault.
You also have some weird things going on in your code. void main() and you use cout without either saying std::cout or using namespace std; or something similar. An odd practice.
Also don't you think you should pass the arrays as arguments if you're going to make lcm() a function? That is int lcm(int a[], int b[]);.
You might look into using a debugger also and improving your coding practices. I found this error within 30 seconds of pasting your code into the compiler with the help of the debugger.
Your loop condition is:
while(n==1&&i<20)
So your equl function will never return 1 because if n happens to be 1 then the loop will just keep going and never return a 1.
However, your program still does not appear to return the correct result. You can split the piece of your code that finds the minimum element and replace it with this for cleanliness:
int least(int a[], int size){
int minPos = 0;
for(int i=0; i<size ;i++){
if (a[i] < a[minPos] ){
minPos = i;
}
}
return minPos;
}
Then you can call it by saying j = least(a, 20);. I will leave further work on your program to you. Consider calling your variables something meaningful instead of i,j,k,a,b.
Your equl function is using array indices from 0-20, but the arrays only have 1-19
j in lcm() is uninitialized if the first element is the smallest. It should be set to 0 at the top of the while loop
In the following code, when i=19, you are accessing a[20], which is out of the bounds of the array. Should be for(i=0;i<19;i++)
for(i=0;i<20;i++) {
if(a[i+1]<k)
You are not actually using the std namespace for the cout. this should be std::cout<<l
Your are including iostream.h. The standard is iostream without the .h, this may not work on such an old compiler tho
instead of hard-coding 20 everywhere, you should use a #define. This is not an error, just a style thing.
The following code does nothing. This is the default behavior
else
continue;