-1

我正在尝试在 C++ 中进行一些基因编程。我已经用 Python 编写了这个代码的一个版本,它运行良好(它只是太慢了)。基本前提是将程序视为树状表达式并对其进行进化。

这是仅创建一棵候选树的代码(树存储为节点的向量,这些节点通过同一向量中子节点的索引指向其子节点)(请参阅grow_tree 函数):

这段代码编译得很好:) 我正在使用 g++ 进行编译以获取我使用 ./a.out 运行的 a.out 文件

我的问题是有时它运行并完成得很好,有时它只是挂起并且不做任何事情(也不给我一个错误)

对此的任何帮助将不胜感激!谢谢!

#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <math.h>

const int MAX_TREE_DEPTH = 5;

int randint(int min, int max) {
    return (rand() % ((max - min) + 1)) + min;
}

struct node {
    int type, op, req_ch;
    std::vector<int> ch;
    std::map<std::string, float> params;
    node(int p, int rem_depth) {
        if ((p == -1) || (p == 0)) {
            req_ch = 2;
            if (rem_depth >= 2) { 
                type = randint(0, 1); 
                if (type == 0) { 
                    op = randint(0, 1); 
                } else if (type == 1) { 
                    op = randint(2, 5); 
                }
            } else { 
                type = 1; 
                op = randint(2, 5); 
            }
        } else if (p == 1) { 
            type = 2;  
            if (rem_depth >= 1) { 
                op =  randint(6, 11); 
            } else { op = 11; }
            if ((op >= 6) && (op <= 10)) { 
                req_ch = 2; 
            } else if (op >= 11) { req_ch = 0; }
        }
    }    
};

void grow_tree(std::vector<node>* func, int p, int rem_depth) {
    node n(p, rem_depth);
    func->push_back(n);
    int i = func->size() - 1;
    for (int j = 0; j < n.req_ch; j++) {
        func->at(i).ch.push_back(func->size());
        grow_tree(func, n.type, rem_depth - 1);
    }
}


struct rule {
    float score;
    bool scored;
    std::vector<node> func;
    rule(int m) {
        if (m == 0) { // Random initialisation
            int depth = randint(2, MAX_TREE_DEPTH);
            grow_tree(&func, -1, depth);
        }
    }
};


int main(void) {
    srand(time(NULL));  // Seed the random number generator
    int depth = randint(2, MAX_TREE_DEPTH);
    std::vector<node> f;
    grow_tree(&f, -1, depth);
    return 0;
}
4

1 回答 1

0

正如@molbdnilo 所指出的,您的node构造函数很容易在构造函数返回后具有未初始化的变量。然后,您可以在此处使用node实例变量grow_tree

for (int j = 0; j < n.req_ch; j++) {

如果n.req_ch是未初始化的或“狂野”的值,则循环可能会持续很长时间。想象一下,如果n.req_ch返回的值接近(假设为 32 位整数)2^32 - 1,. 您的循环将进行超过 2,000,000,000 次迭代。

为了确认这一点,如果您将变量的成员初始化node为一个值,您可以轻松地输出这些变量以查看初始值是否已更改。如果该值未更改,则确认您在grow_tree函数中使用了未初始化的值。

例子:

node(int p, int rem_depth) :type(-100), op(-100), req_ch(-100) // Initialize everything to -100
{
   // your code
 ...
   // now check if all the variables have been initialized (values were changed from -100)
   if ( type == -100 || op == -100 || req_ch == -100 )
   {
       std::cout << "Oops.  I'm using uninitialized values for p = " << p << 
      " rem_depth = " << rem_depth << "\n";
       std::cout << type << " " << op << " " << req_ch << "\n\n";
    }   
}

这是您的代码,已通过检查进行了修改。

如您所见,您的node构造函数并没有设置所有值,并且您稍后会在grow_tree.

因此,您的问题的答案是返回并堵塞node构造函数中的孔,以便初始化您的变量。

于 2018-07-04T17:49:24.910 回答