Genetic Algorithm - Crossover and MPI - c++

i got stuck when i was trying to convert my code to MPI and Crossover solution. My problem is about the Crossover is too hard for me to understand and more difficult to implement all of those solution to MPI. If anyone could give me hint, or example, or any related document. I will included my code below for everyone to see.
Thank you very much
#include <string>
#include <cstdlib>
#include <iostream>
#include <cassert>
#include <algorithm>
#include <vector>
std::string allowed_chars = " ABCDEFGHIJKLMNOPQRSTUVWXYZ";
class selection
{
public:
static int fitness(std::string candidate)
{
assert(target.length() == candidate.length());
int fitness_so_far = 0;
for (int i = 0; i < target.length(); ++i)
{
int target_pos = allowed_chars.find(target[i]);
int candidate_pos = allowed_chars.find(candidate[i]);
int diff = std::abs(target_pos - candidate_pos);
fitness_so_far -= std::min(diff, int(allowed_chars.length()) - diff);
}
return fitness_so_far;
}
// get the target string length
static int target_length() { return target.length(); }
private:
static std::string target;
};
std::string selection::target = "METHINKS IT IS LIKE A WEASEL";
void move_char(char& c, int distance)
{
while (distance < 0)
distance += allowed_chars.length();
int char_pos = allowed_chars.find(c);
c = allowed_chars[(char_pos + distance) % allowed_chars.length()];
}
std::string mutate(std::string parent, double mutation_rate)
{
for (int i = 0; i < parent.length(); ++i)
if (std::rand()/(RAND_MAX + 1.0) < mutation_rate)
{
int distance = std::rand() % 3 + 1;
if(std::rand()%2 == 0)
move_char(parent[i], distance);
else
move_char(parent[i], -distance);
}
return parent;
}
bool less_fit(std::string const& s1, std::string const& s2)
{
return selection::fitness(s1) < selection::fitness(s2);
}
int main()
{
int const C = 100;
std::srand(time(0));
std::string parent;
for (int i = 0; i < selection::target_length(); ++i)
{
parent += allowed_chars[std::rand() % allowed_chars.length()];
}
int const initial_fitness = selection::fitness(parent);
for(int fitness = initial_fitness;
fitness < 0;
fitness = selection::fitness(parent))
{
std::cout << parent << ": " << fitness << "\n";
double const mutation_rate = 0.02 + (0.9*fitness)/initial_fitness;
typedef std::vector<std::string> childvec;
childvec childs;
childs.reserve(C+1);
childs.push_back(parent);
for (int i = 0; i < C; ++i)
childs.push_back(mutate(parent, mutation_rate));
parent = *std::max_element(childs.begin(), childs.end(), less_fit);
}
std::cout << "final string: " << parent << "\n";
}

For cross over select 2 parents strings and associated split index(es),
then generate 2 new string:
std::string new_string1 = s1.substring(0, split_index1) + s2.substring(split_index2);
std::string new_string2 = s2.substring(0, split_index2) + s1.substring(split_index1);`.

Related

Solving String Factoring

I'm trying to solve a question from kattis as shown here regarding string factorisation. I've tried adjusting my code for quite abit but it still seems theoretically correct. Not sure why it still fails for some of the test cases.
#include <stdio.h>
#include <iostream>
#include <string>
#include <map>
#include <algorithm>
using namespace std;
string shortener (string input) {
map<string, int> freq;
int flag = 0;
for (int i = (input.length())/2; i >= 1 && !flag; i--) {
for (int d = 0; d + i + i <= input.length(); d++) {
if (input.substr(d, i) == input.substr(d + i, i)) {
freq[input.substr(d,i)]++;
flag = 1; // stop at this size
}
}
}
int largest = 0;
if (freq.empty()) return input;
//string largest;
auto x = max_element(freq.begin(), freq.end(),
[](const pair<string, int>& p1, const pair<string, int>& p2) {
return p1.second < p2.second; });
if (x->first == input) return input;
int a = input.find(x->first);
for (int i = 0; i < x->second ; i++) {
input.replace(a, x->first.length(), "");
a = input.find(x->first);
}
if (a != -1) {
if (!input.substr(0, a).empty())
input.replace(0, a, shortener(input.substr(0, a)));
if (!input.substr(a + x->first.length()-1, input.length()-1).empty())
input.replace(a + x->first.length()-1, input.length()-1, shortener(input.substr(a + x->first.length()-1, input.length()-1)));
//cout << input.substr(a + x->first.length()-1, input.length()-1) << endl;
input.replace(a, x->first.length(), shortener(x->first));
}
return input;
}
int main () {
string input;
cin >> input;
cout << shortener(input).length() << endl;
}
I know my code may not be the most efficient, but I'm hoping to find out what kind of test case might potentially break my code.

How to print to the console after every swap using any sorting algorithm?

In my Intro to Computer Science class I am beginning to learn the basics of sorting algorithms. So far, we have gone over Bubble, Selection, and Insertion Sort.
After class today, the instructor has requested us to "enhance" the program by adding code to print out the vector/array after every swap during the sorting. I am at a complete loss as to how I would make this happen. I'm thinking something like :
if (swapped) { cout << vec << " "; }
but without even trying, I'm certain this wouldn't work. Any help is very much appreciated. Here's my code so far:
#include <string>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> createVec(int n) {
unsigned seed = time(0);
srand(seed);
vector<int> vec;
for (int i = 1; i <= n; ++i) {
vec.push_back(rand() % 100 + 1);
}
return vec;
}
void showVec(vector<int> vec) {
for (int n : vec) {
cout << n << " ";
}
}
void bubbleSort(vector<int> &vec) {
int n = vec.size();
bool swapped = true;
while (swapped) {
swapped = false;
for (int i = 1; i <= n-1; ++i) {
if (vec[i-1] > vec[i]) {
swap(vec[i-1], vec[i]);
swapped = true;
}
}
}
}
void selectionSort(vector<int> &vec) {
int n = vec.size();
int maxIndex;
for (int i = 0; i <= n-2; ++i) {
maxIndex = i;
for (int j = i+1; j <= n-1; ++j) {
if (vec[j] < vec[maxIndex]) {
maxIndex = j;
}
}
swap(vec[i], vec[maxIndex]);
}
}
int main()
{
vector<int> numbers = createVec(20);
showVec(numbers);
cout << endl;
//bubbleSort(numbers);
selectionSort(numbers);
showVec(numbers);
return 0;
}
For example in the called function selectionSort substitute this statement
swap(vec[i], vec[maxIndex]);
for the following statement
if ( i != maxIndex )
{
swap(vec[i], vec[maxIndex]);
showVec( vec );
cout << endl;
}
Also the function showVec should declare the parameter as having a constant referenced type
void showVec( const vector<int> &vec) {
for (int n : vec) {
cout << n << " ";
}
}

MSVC Debugger tells me that my vector has more positions than specified

I have declared the following:
const int NUMBER_OF_DIGITS = 16;
std::vector<int> digits(NUMBER_OF_DIGITS);
However when I open the MSVC debugger it shows the following:
This is how I added values to the vector:
for (int i = 0; i < NUMBER_OF_DIGITS; ++i) {
scanf("%d", &digits[i]);
}
Is this normal? Can I just ignore this? Or is this a problem?
Full code(the program is still not ready yet):
#include <iostream>
#include <vector>
#include "stdio.h"
const int NUMBER_OF_DIGITS = 16;
int checksum, tmp1, tmp2, tmp3, sum = 0;
std::vector<int> digits(NUMBER_OF_DIGITS);
std::vector<int> new_digits(NUMBER_OF_DIGITS);
int luhn_checksum(std::vector<int> cardnumber[NUMBER_OF_DIGITS]) {
//step 1: duouble every second number
for (int i = 1; i < NUMBER_OF_DIGITS; i += 2) {
new_digits[i] = digits[i] * 2;
if (new_digits[i] > 9) {
//if the product is larger than 9 we will add the two numbers together
//example: 9 * 2 = 18 so we will add 1 + 8 to get 9
tmp1 += new_digits[i] % 10;
new_digits[i] /= 10;
tmp1 = 0;
}
}
//step 2: sum all the values
for (int i = 0; i < NUMBER_OF_DIGITS; ++i) {
checksum += new_digits[i];
}
return checksum;
}
void get_card_numbers(void) {
for (int i = 0; i < NUMBER_OF_DIGITS; ++i) {
scanf("%d", &digits[i]);
}
}
void initialize(void) {
for (int i = 0; i < NUMBER_OF_DIGITS; ++i) {
digits.push_back(0);
new_digits.push_back(0);
}
}
int main() {
initialize();
get_card_numbers();
printf("checksum is: %d\n", luhn_checksum(&digits));
std::cout << digits.size() << std::endl;
int x; scanf("%d", &x);
return 0;
}
The constructor you're using for digits is setting the size by specifying the count. So after calling push_back you've just added another 16 to the vector. Use a different constructor that doesn't set the count.
int _tmain(int argc, _TCHAR* argv[])
{
const int NUMBER_OF_DIGITS = 16;
std::vector<int> digits(NUMBER_OF_DIGITS);
//std::vector<int> digits;
int digitsLen = digits.size();
// Here is 16
for (int i = 0; i < NUMBER_OF_DIGITS; ++i) {
digits.push_back(0);
}
int digitsLen2 = digits.size();
// Here is 32
return 0;
}
Cleaned up your code a bit:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
static const size_t NUMBER_OF_DIGITS = 16;
class cards {
public:
cards();
void read();
int luhnChecksum() const;
private:
vector<int> digits;
};
cards::cards() : digits(NUMBER_OF_DIGITS, 0)
{
}
void cards::read() {
for_each(digits.begin(), digits.end(), [](int& i) { cin >> i; });
}
int cards::luhnChecksum() const {
vector<int> newdigits(digits.begin(), digits.end());
for (size_t i=1; i<NUMBER_OF_DIGITS; i += 2) {
newdigits[i] = digits[i] * 2;
if (newdigits[i] > 9) {
int tmp1 = newdigits[i] % 10;
newdigits[i] /= 10;
newdigits[i] += tmp1;
}
}
return accumulate(newdigits.begin(), newdigits.end(), 0);
}
int main() {
cards c;
c.read();
cout << "checksum = " << c.luhnChecksum() << endl;
return 0;
}

Why is my code in C++ so much slower than my code in C [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
So far, I wrote my code in C (performance is of utmost importance). However, I would like to start writing my algorithms in a generic way. So, I decided to try out C++. I took a simple code in C and translated it into C++ with templates. To my disappointment, the C++ code runs 2.5 times slower. (the C code is compiled with gcc -O3; the C++ code is compiled with g++ -O3)
Am I doing something wrong in C++? Why is there such a performance hit?
Here is the C code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
static int df_output = 0;
int nCalls = 0;
typedef struct {
int *pancakes;
int n;
} STATE;
STATE **solution;
void shuffle(STATE *s) {
int i;
for (i = 0; i < s->n; i++) {
int i1 = rand() % s->n;
int i2 = rand() % s->n;
int temp = s->pancakes[i1];
s->pancakes[i1] = s->pancakes[i2];
s->pancakes[i2] = temp;
}
}
STATE *copyState(STATE *s) {
STATE *res = malloc(sizeof(STATE));
res->n = s->n;
res->pancakes = (int *)malloc(res->n * sizeof(int));
memcpy(res->pancakes, s->pancakes, res->n * sizeof(int));
return res;
}
// reverse n pancakes
void makeMove(STATE *s, int n) {
int i;
for (i = 0; i < n/2; i++) {
int temp = s->pancakes[i];
s->pancakes[i] = s->pancakes[n - 1 - i];
s->pancakes[n - 1 - i]=temp;
}
}
void printState(STATE *s) {
int i;
printf("[");
for (i = 0; i < s->n; i++) {
printf("%d", s->pancakes[i]);
if (i < s->n - 1)
printf(", ");
}
printf("]");
}
int heuristic(STATE *s) {
int i, res = 0;
nCalls++;
for (i = 1; i < s->n; i++)
if (abs(s->pancakes[i]-s->pancakes[i-1])>1)
res++;
if (s->pancakes[0] != 0) res++;
return res;
}
void tabs(int g) {
int i;
for (i = 0; i < g; i++) printf("\t");
}
int df(STATE *s, int g, int left) {
int h = heuristic(s), i;
if (g == 0) printf("Thereshold: %d\n", left);
if (df_output) {
tabs(g);
printf("g=%d,left=%d ", g, left); printState(s); printf("\n");}
if (h == 0) {
assert(left == 0);
solution = (STATE **)malloc((g+1) * sizeof(STATE *));
solution[g] = copyState(s);
return 1;
}
if (left == 0)
return 0;
for (i = 2; i <= s->n; i++) {
makeMove(s, i);
if (df(s, g+1, left-1)) {
makeMove(s, i);
solution[g] = copyState(s);
return 1;
}
makeMove(s, i);
}
return 0;
}
void ida(STATE *s) {
int threshold = 0, i;
while (!df(s, 0, threshold)) threshold++;
for (i = 0; i <= threshold; i++) {
printf("%d. ", i);
printState(solution[i]);
printf("\n");
//if (i < threshold - 1) printf("->");
}
}
int main(int argc, char **argv) {
STATE *s = (STATE *)malloc(sizeof(STATE));
int i, n;
int myInstance[] = {0,5,4,7,2,6,1,3};
s->n = 8;
s->pancakes = myInstance;
printState(s); printf("\n");
ida(s);
printf("%d calls to heuristic()", nCalls);
return 0;
}
Here is the C++ code:
#include <iostream>
#include "stdlib.h"
#include "string.h"
#include "assert.h"
using namespace std;
static int df_output = 0;
int nCalls = 0;
class PancakeState {
public:
int *pancakes;
int n;
PancakeState *copyState();
void printState();
};
PancakeState *PancakeState::copyState() {
PancakeState *res = new PancakeState();
res->n = this->n;
res->pancakes = (int *)malloc(this->n * sizeof(int));
memcpy(res->pancakes, this->pancakes,
this->n * sizeof(int));
return res;
}
void PancakeState::printState() {
int i;
cout << "[";
for (i = 0; i < this->n; i++) {
cout << this->pancakes[i];
if (i < this->n - 1)
cout << ", ";
}
cout << "]";
}
class PancakeMove {
public:
PancakeMove(int n) {this->n = n;}
int n;
};
class Pancake {
public:
int heuristic (PancakeState &);
int bf(PancakeState &);
PancakeMove *getMove(int);
void makeMove(PancakeState &, PancakeMove &);
void unmakeMove(PancakeState &, PancakeMove &);
};
int Pancake::bf(PancakeState &s) {
return s.n - 1;
}
PancakeMove *Pancake::getMove(int i) {
return new PancakeMove(i + 2);
}
// reverse n pancakes
void Pancake::makeMove(PancakeState &s, PancakeMove &m) {
int i;
int n = m.n;
for (i = 0; i < n/2; i++) {
int temp = s.pancakes[i];
s.pancakes[i] = s.pancakes[n - 1 - i];
s.pancakes[n - 1 - i]=temp;
}
}
void Pancake::unmakeMove(PancakeState &state, PancakeMove &move) {
makeMove(state, move);
}
int Pancake::heuristic(PancakeState &s) {
int i, res = 0;
nCalls++;
for (i = 1; i < s.n; i++)
if (abs(s.pancakes[i]-s.pancakes[i-1])>1)
res++;
if (s.pancakes[0] != 0) res++;
return res;
}
void tabs(int g) {
int i;
for (i = 0; i < g; i++) cout << "\t";
}
template <class Domain, class State, class Move>
class Alg {
public:
State **solution;
int threshold;
bool verbose;
int df(Domain &d, State &s, int g);
void ida(Domain &d, State &s);
};
template <class Domain, class State, class Move>
int Alg<Domain, State, Move>::df(Domain &d, State &s, int g) {
int h = d.heuristic(s), i;
if (g == 0)
cout << "Thereshold:" << this->threshold << "\n";
if (this->verbose) {
tabs(g);
cout << "g=" << g;
s.printState(); cout << "\n";
}
if (h == 0) {
solution = (State **)malloc((g+1) * sizeof(State *));
solution[g] = s.copyState();
return 1;
}
if (g == this->threshold)
return 0;
for (i = 0; i < d.bf(s); i++) {
Move *move = d.getMove(i);
d.makeMove(s, *move);
if (this->df(d, s, g+1)) {
d.unmakeMove(s, *move);
solution[g] = s.copyState();
delete move;
return 1;
}
d.unmakeMove(s, *move);
delete move;
}
return 0;
}
template <class Domain, class State, class Move>
void Alg<Domain, State, Move>::ida(Domain &d, State &s) {
int i;
this->threshold = 0;
while (!this->df(d, s, 0)) threshold++;
for (i = 0; i <= threshold; i++) {
cout << i << ".";
this->solution[i]->printState();
cout << "\n";
//if (i < threshold - 1) printf("->");
}
}
int main(int argc, char **argv) {
Pancake *d = new Pancake();
PancakeState *s = new PancakeState();
int myInstance[] = {0,5,4,7,2,6,1,3};
s->pancakes = myInstance;
s->n = 8;
s->printState(); cout << "\n";
Alg<Pancake, PancakeState, PancakeMove> *alg = new Alg<Pancake, PancakeState, PancakeMove>();
//alg->verbose = true;
alg->ida(*d, *s);
cout << nCalls < "calls to heuristic()";
delete alg;
return 0;
}
You have a lot of malloc() and operator new calls in there. Stop doing that, and performance will improve. And don't use malloc() in C++, use operator new always.
For example, PancakeMove is a small, trivial struct. But you allocate instances of it dynamically, which is slow. Just pass it around by value.
Basically, you are allocating a lot of small things on the heap instead of on the stack. That's pretty "expensive", so will take extra time.
This code (which is modified from your original code) runs within 1ms of the C code:
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <vector>
using namespace std;
static int df_output = 0;
int nCalls = 0;
class PancakeState {
public:
PancakeState(int n) : n(n), pancakes(n)
{
}
PancakeState(int n, int *v) : n(n), pancakes(n)
{
for(int i = 0; i < n; i++)
pancakes[i] = v[i];
}
PancakeState(): n(0) {}
public:
vector<int> pancakes;
int n;
PancakeState *copyState();
void printState();
};
void PancakeState::printState() {
int i;
cout << "[";
for (i = 0; i < this->n; i++) {
cout << this->pancakes[i];
if (i < this->n - 1)
cout << ", ";
}
cout << "]";
}
class PancakeMove {
public:
PancakeMove(int n) : n(n) {}
int n;
};
class Pancake {
public:
int heuristic (PancakeState &);
int bf(PancakeState&);
PancakeMove getMove(int);
void makeMove(PancakeState &, PancakeMove &);
void unmakeMove(PancakeState &, PancakeMove &);
};
int Pancake::bf(PancakeState& s) {
return s.n - 1;
}
PancakeMove Pancake::getMove(int i) {
return PancakeMove(i + 2);
}
// reverse n pancakes
void Pancake::makeMove(PancakeState &s, PancakeMove &m) {
int i;
int n = m.n;
for (i = 0; i < n/2; i++) {
int temp = s.pancakes[i];
s.pancakes[i] = s.pancakes[n - 1 - i];
s.pancakes[n - 1 - i]=temp;
}
}
void Pancake::unmakeMove(PancakeState &state, PancakeMove &move) {
makeMove(state, move);
}
int Pancake::heuristic(PancakeState &s) {
int i, res = 0;
nCalls++;
for (i = 1; i < s.n; i++)
if (abs(s.pancakes[i]-s.pancakes[i-1])>1)
res++;
if (s.pancakes[0] != 0) res++;
return res;
}
void tabs(int g) {
int i;
for (i = 0; i < g; i++) cout << "\t";
}
template <class Domain, class State, class Move>
class Alg {
public:
vector<State> solution;
int threshold;
bool verbose;
int df(Domain &d, State &s, int g);
void ida(Domain &d, State &s);
};
template <class Domain, class State, class Move>
int Alg<Domain, State, Move>::df(Domain &d, State &s, int g) {
int h = d.heuristic(s), i;
if (g == 0)
cout << "Thereshold:" << threshold << "\n";
if (this->verbose) {
tabs(g);
cout << "g=" << g;
s.printState(); cout << "\n";
}
if (h == 0) {
solution.resize(g+1);
solution[g] = s;
return 1;
}
if (g == this->threshold)
return 0;
for (i = 0; i < d.bf(s); i++) {
Move move = d.getMove(i);
d.makeMove(s, move);
if (this->df(d, s, g+1)) {
d.unmakeMove(s, move);
solution[g] = s;
return 1;
}
d.unmakeMove(s, move);
}
return 0;
}
template <class Domain, class State, class Move>
void Alg<Domain, State, Move>::ida(Domain &d, State &s) {
int i;
this->threshold = 0;
while (!this->df(d, s, 0)) threshold++;
for (i = 0; i <= threshold; i++) {
cout << i << ".";
solution[i].printState();
cout << "\n";
//if (i < threshold - 1) printf("->");
}
}
int main(int argc, char **argv) {
Pancake d = Pancake();
int myInstance[] = {0,5,4,7,2,6,1,3};
PancakeState s(8, myInstance);
s.printState(); cout << "\n";
Alg<Pancake, PancakeState, PancakeMove> *alg = new Alg<Pancake, PancakeState, PancakeMove>();
//alg->verbose = true;
alg->ida(d, s);
cout << nCalls < "calls to heuristic()";
delete alg;
return 0;
}
As an extra benefit of not making so many direct allocations, it also doesn't leak 22 lumps of memory throughout the execution, which is quite a useful feature.
(If you want to see what changed, here's a diff - ignoring whitespace only changes):
--- pcake.orig.cpp 2014-04-13 15:43:24.861417827 +0100
+++ pcake.cpp 2014-04-13 15:42:25.145165372 +0100
## -1,7 +1,9 ##
#include <iostream>
-#include "stdlib.h"
-#include "string.h"
-#include "assert.h"
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <vector>
+
using namespace std;
static int df_output = 0;
## -9,21 +11,22 ##
class PancakeState {
public:
- int *pancakes;
+ PancakeState(int n) : n(n), pancakes(n)
+ {
+ }
+ PancakeState(int n, int *v) : n(n), pancakes(n)
+ {
+ for(int i = 0; i < n; i++)
+ pancakes[i] = v[i];
+ }
+ PancakeState(): n(0) {}
+public:
+ vector<int> pancakes;
int n;
PancakeState *copyState();
void printState();
};
-PancakeState *PancakeState::copyState() {
- PancakeState *res = new PancakeState();
- res->n = this->n;
- res->pancakes = (int *)malloc(this->n * sizeof(int));
- memcpy(res->pancakes, this->pancakes,
- this->n * sizeof(int));
- return res;
-}
-
void PancakeState::printState() {
int i;
cout << "[";
## -37,25 +40,25 ##
class PancakeMove {
public:
- PancakeMove(int n) {this->n = n;}
+ PancakeMove(int n) : n(n) {}
int n;
};
class Pancake {
public:
int heuristic (PancakeState &);
- int bf(PancakeState &);
- PancakeMove *getMove(int);
+ int bf(PancakeState&);
+ PancakeMove getMove(int);
void makeMove(PancakeState &, PancakeMove &);
void unmakeMove(PancakeState &, PancakeMove &);
};
-int Pancake::bf(PancakeState &s) {
+int Pancake::bf(PancakeState& s) {
return s.n - 1;
}
-PancakeMove *Pancake::getMove(int i) {
- return new PancakeMove(i + 2);
+PancakeMove Pancake::getMove(int i) {
+ return PancakeMove(i + 2);
}
// reverse n pancakes
## -91,7 +94,7 ##
template <class Domain, class State, class Move>
class Alg {
public:
- State **solution;
+ vector<State> solution;
int threshold;
bool verbose;
int df(Domain &d, State &s, int g);
## -102,30 +105,28 ##
int Alg<Domain, State, Move>::df(Domain &d, State &s, int g) {
int h = d.heuristic(s), i;
if (g == 0)
- cout << "Thereshold:" << this->threshold << "\n";
+ cout << "Thereshold:" << threshold << "\n";
if (this->verbose) {
tabs(g);
cout << "g=" << g;
s.printState(); cout << "\n";
}
if (h == 0) {
- solution = (State **)malloc((g+1) * sizeof(State *));
- solution[g] = s.copyState();
+ solution.resize(g+1);
+ solution[g] = s;
return 1;
}
if (g == this->threshold)
return 0;
for (i = 0; i < d.bf(s); i++) {
- Move *move = d.getMove(i);
- d.makeMove(s, *move);
+ Move move = d.getMove(i);
+ d.makeMove(s, move);
if (this->df(d, s, g+1)) {
- d.unmakeMove(s, *move);
- solution[g] = s.copyState();
- delete move;
+ d.unmakeMove(s, move);
+ solution[g] = s;
return 1;
}
- d.unmakeMove(s, *move);
- delete move;
+ d.unmakeMove(s, move);
}
return 0;
}
## -138,23 +139,22 ##
for (i = 0; i <= threshold; i++) {
cout << i << ".";
- this->solution[i]->printState();
+ solution[i].printState();
cout << "\n";
//if (i < threshold - 1) printf("->");
}
}
int main(int argc, char **argv) {
- Pancake *d = new Pancake();
- PancakeState *s = new PancakeState();
+ Pancake d = Pancake();
int myInstance[] = {0,5,4,7,2,6,1,3};
- s->pancakes = myInstance;
- s->n = 8;
- s->printState(); cout << "\n";
+ PancakeState s(8, myInstance);
+ s.printState(); cout << "\n";
Alg<Pancake, PancakeState, PancakeMove> *alg = new Alg<Pancake, PancakeState, PancakeMove>();
//alg->verbose = true;
- alg->ida(*d, *s);
+ alg->ida(d, s);
cout << nCalls < "calls to heuristic()";
delete alg;
return 0;
}
+

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