C ++脚本有时会运行,有时会挂起

时间:2018-07-04 16:57:27

标签: c++ vector tree genetic-algorithm

我正在尝试用C ++进行一些遗传编程。我用Python编写了此代码的一个版本,它工作得很好(这只是FAR TOO SLOW)。基本前提是将程序视为树状表达式并将其演化。

这里是仅创建一棵候选树的代码(树被存储为节点的向量,并通过同一向量中子节点的索引指向其子节点)(请参见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;
}

1 个答案:

答案 0 :(得分: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";
    }   
}

Here is your code, modified with the check.

如您所见,您的node构造函数并未设置所有值,稍后您将在grow_tree中使用这些值。

因此,解决您问题的方法是返回并堵塞node构造函数中的漏洞,以便初始化变量。