我怎样才能使这个算法的内存效率更高?

How can i make this algorithm more memory efficient?

我已经在这段代码上工作了几天,看起来 对于相对较小的搜索树工作得很好,但使用较大的搜索树会出现分段错误。

我试图通过使用打印标志找到此类错误的具体来源,但它似乎在 is_goal() 函数处中断。但是那个函数的代码可以假设是正确的。

所以问题似乎是内存问题,这就是为什么我在堆中有队列,还有我正在创建的节点。但它仍然崩溃。

是否有更多我没有使用的内存节省技巧可以考虑在内?或者也许有更好的方法来保存这些节点?

需要注意的是我需要使用BFS(我不能使用A*让搜索树变小)

此外,如果您需要知道,地图是一个散列 table,我在其中保存节点的颜色,因此在探索时我没有重复(这是因为散列根据状态保存信息而不是节点信息)。

编辑:我被告知要指出要完成的目标,例如在搜索树中找到目标状态,目标是能够迭代 像 rubik 3x3x3、n-puzzle 4x4 5x5、河内塔和 such.To 这样的大问题,使用的内存必须是最小的,因为这些问题的搜索树非常大,最后的 objective 是将该算法与 a*、dfid、ida* 等其他算法进行比较。我希望这是足够的信息。

  Node* BFS(state_t start ){

    state_t state, child;  
    int d, ruleid;
    state_map_t *map = new_state_map();
    ruleid_iterator_t iter;
    std::queue<Node*> *open = new std::queue<Node*>();

    state_map_add( map, &start, 1); 

    Node* n = new Node(start);
    open->push(n);

    while( !open->empty() ) {
        n = open->front();
        state = n->get_state();
        open->pop();

        if (is_goal(&state) == 1) return n;

        init_fwd_iter( &iter, &state ); 

        while( ( ruleid = next_ruleid( &iter ) ) >= 0 ) {
            apply_fwd_rule( ruleid, &state, &child );


            const int *old_child_c = state_map_get( map, &child );
            if ( old_child_c == NULL ) {
                state_map_add( map, &child, 1 );
                Node* nchild = new Node(child); 
                open->push(nchild);
            }

        }

    }

    return NULL;
}  

我看到了一些内存泄漏。

open 永远不会被删除,但也许可以分配到堆栈而不是堆中。

std::queue<Node*> open;

更重要的none你在队列中推送的节点被删除这可能是非常大的内存消耗的来源。

删除您从队列中移除且您不打算重新使用的节点。在摆脱队列之前删除队列的节点。

Node* BFS(state_t start ){

    state_t state, child;  
    int d, ruleid;
    state_map_t *map = new_state_map();
    ruleid_iterator_t iter;
    std::queue<Node*> open;

    state_map_add( map, &start, 1); 

    Node* n = new Node(start);
    open.push(n);

    while( !open.empty() ) {
        n = open.front();
        state = n->get_state();
        open.pop();

        if (is_goal(&state) == 1) {
            for (std::queue<Node*>::iterator it = open.begin(); it != open.end(); ++it)
                delete *it;

            return n;
        }
        else {
            delete n;
        }

        init_fwd_iter( &iter, &state ); 

        while( ( ruleid = next_ruleid( &iter ) ) >= 0 ) {
            apply_fwd_rule( ruleid, &state, &child );


            const int *old_child_c = state_map_get( map, &child );
            if ( old_child_c == NULL ) {
                state_map_add( map, &child, 1 );
                Node* nchild = new Node(child); 
                open.push(nchild);
            }

        }

    }

    return NULL;
}