简体   繁体   English

如何避免深度树递归中的堆栈溢出

[英]How to avoid stack overflow in deep tree recursion

I've read many similar articles, I apologise if this has already been answered, but I'm still stuck.我读过很多类似的文章,如果这已经得到回答,我很抱歉,但我仍然卡住了。

I'm coding a function to populate a tree, each node having four branches, which will store the possible manipulation of states of the "eight tile puzzle" ie http://www.8puzzle.com/images/8_puzzle_start_state_a.png我正在编写一个 function 来填充一棵树,每个节点都有四个分支,它们将存储对“八块拼图”状态的可能操作,即http://www.8puzzle.com/images/8_puzzle_start_state_a.png

The problem is I've reached, what I believe to be, stack overflow, due to the heavily recursive nature of the problem at hand.问题是我已经达到了,我认为是堆栈溢出,由于手头问题的严重递归性质。

Tail recursion seems like the solution, though I'm not sure if it is relevant/possible or how to implement it in this instance.尾递归似乎是解决方案,但我不确定它是否相关/可能或如何在这种情况下实现它。 Code follows:代码如下:

void Tree::insert(string &initialState, const string &goalState, tree_node *&inNode){
cout<<"insert called"<<endl;
depth++;
cout<<depth<<endl;
string modState;
int zeroPos=0;

if(initialState==goalState){
    cout<<"*    *   *   GOAL    *   *   *"<<endl;
    getchar();
    exit(0);
}   

if(inNode==NULL){//is this the first node?

    inNode = new tree_node(initialState);       
    root=inNode;
    inNode->parent=NULL;
    insert(initialState, goalState, inNode);
}else{
    inNode->state = initialState;

    for(zeroPos=0;zeroPos<initialState.size();zeroPos++){//where is the empty tile?
        if(initialState[zeroPos]=='0'){
            break;
        }
    }
    //left
    if(zeroPos!=0 && zeroPos!=3 && zeroPos!=6){//can the empty tile move left?

        modState=initialState;
        modState[zeroPos]=modState[zeroPos-1];
        modState[zeroPos-1]='0';

        if(isOriginal(modState, inNode) ){//does this state already exist?

            cout <<"left  " << modState[0]<<modState[1]<<modState[2]<<endl;
            cout <<"left  " << modState[3]<<modState[4]<<modState[5]<<endl;
            cout <<"left  " << modState[6]<<modState[7]<<modState[8]<<endl;

            inNode->l = new tree_node(modState);    
            inNode->l->parent= inNode;
            if(inNode->l != NULL){
                insert(modState, goalState, inNode->l);
            }
        }
    }

    }
 }
}

This is a very generic answer, but have you tried to explicitly manage your stack through something like a heap allocated queue or a stack?这是一个非常通用的答案,但是您是否尝试过通过堆分配队列或堆栈之类的方式显式管理您的堆栈? Basically don't use actually function calls, just push and pull things off your own stack/queue.基本上不要实际使用 function 调用,只需从您自己的堆栈/队列中推送和拉取东西。 They cover non-recursive graph traversal algorithms here (both depth first, and breadth first search).它们在这里涵盖了非递归图遍历算法(深度优先和广度优先搜索)。

Optimize your code, meaning only keep those nodes you need.优化您的代码,这意味着只保留您需要的那些节点。 For example only keep leaf nodes (I mean the ones you haven't yet expaneded).例如只保留叶节点(我的意思是那些你还没有展开的节点)。 And yes you can search the tree while building it, write a function to measure the distance between your current state and your goal state, its called heuristic.是的,您可以在构建树时搜索树,编写 function 来测量当前 state 和目标 state 之间的距离,这称为启发式。 There's also a better algorithm that solves 8puzzle, it's called A*, I suggest you google it.还有一个更好的算法可以解决8puzzle,它叫做A*,我建议你google一下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM