0

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;
}
4

2 回答 2

1
a1.~vector();
a2.~vector();
b1.~vector();
b2.~vector();

您不应手动破坏向量,否则下次尝试访问它们时(在下一次调用 operator () 时)您会得到未定义的行为。

于 2012-10-22T17:04:23.900 回答
0

为什么要vector手动调用析构函数?您应该让 C++ 为您调用它。如果要清除vector使用clear成员函数

于 2012-10-22T17:07:02.117 回答