0

私は遺伝的アルゴリズムを書いています.2つの親「染色体」に渡されるクラスオブジェクトとして「クロスオーバー」演算子を作成しています.入力と出力染色体は可変長であるため、私の考えは入力を2分割することでした.染色体を保存クラス変数の一種に配置し、入力染色体のサイズを変更し、最後に入力染色体を再充填します。ただし、bad_alloc エラーが発生します。誰かが私のエラーを見つけることができれば、助けていただければ幸いです。

ありがとう!私のクラスコードは以下です。「plan_vector」は int 型の 2 次元ベクトルであることに注意してください。

#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();

ベクトルを手動で破棄してはなりません。そうしないと、次にそれらにアクセスしようとしたときに (演算子 () への次の呼び出し時に)、未定義の動作が発生します。

于 2012-10-22T17:04:23.900 に答える
0

なぜvectorデストラクタを手動で呼び出すのですか?? C++ にそれを呼び出させる必要があります。vector使用clearメンバー関数をクリアしたい場合

于 2012-10-22T17:07:02.117 に答える