PHP树构建函数在深度= 4时中断,但在深度<4时起作用,为什么?

时间:2009-10-23 22:41:10

标签: php cakephp treenode

坦率地说,这是我的单一任务的一部分,但我已经做了很多...所以请感到舒服并继续阅读,因为我不是要求备忘单等:) 该项目现已部署在my website

  

好的,我可能在几分钟前找到了原因:     在数组中推送许多项后,array_push()失败。可笑的小阵列容量???

     

当初始深度设置为3时它起作用,因为77行不会使阵列向上吹;但是初始深度为4将产生超出PHP数组容量的更多行(很奇怪,以前从未考虑过这个)。

     

在注释掉array_push()部分之后,这个树构建函数将工作,初始深度为6的成本超过10秒...所以我想修复将是在PHP中找到另一个可以容纳那么多的集合类型元件...

     

测试表明,在我目前的递归树构建函数中,数组存储中允许的最大行数大约为950 ...超出此范围会导致“隐形”允许内存大小耗尽错误,这会导致PHP脚本死亡从进一步执行。我可以通过引入更多的数组存储对象来解决这个问题。

     

所以请忽略下面的词语,因为现在问题已经改变,焦点不再存在。

猴子级别和新手级别完成没有错误(至少我希望如此)。 在Veteran级别实现minimax搜索算法时遇到了一个奇怪的问题,特别是在尝试构建一个直到第N深度的树时。

我的buildTree函数仅在初始深度设置为不大于3时才有效。 当初始深度设置为2时,它生成16个树节点,设置为3时生成77个树节点。 我认为逻辑有效,因为您可以使用Fire Bug控制台检查它。

此功能的目的是模拟ai / player移动n步。每次移动都会更改游戏板上的单元格状态。请访问上述网站,玩新手游戏,以便了解这是为了什么。

说,这个功能用于AI。 AI采取行动A,然后玩家将根据AI的移动采取他/她的行动B,然后等等......移动后,船上的某些单元需要翻转。得分功能是根据当前游戏板状态评估得分。 当函数完成后,我可以得到一个完整的列表,其中每一行实际上代表树中的一个节点,如下所示:

                                 AI 
                                 |
                           |-----------|
                         PLAYER       PLAYER
                           |           |
            |--------|-----------|  |-------|---------|
           AI       AI          AI AI      AI         AI
                        ......................

下面是有缺陷的功能,花了好几个小时查看它但找不到原因:

function buildTree($gamecells, $depth, $side, $parent)
{   
    //make copies of the arguments passed.
    $currentCells  = $gamecells;
    $currentDepth  = $depth;
    $currentSide   = $side;
    $currentParent = $parent;

    $nextMoves = $this->checkForValidMoves($currentCells, $currentSide);

    if(count($nextMoves) != 0 ) //can still move on.
    {
        foreach($nextMoves as $nextMove)
        {
            $flippedCells = $this->flipCells($currentCells, $nextMove, $side);
            $result = $this->getScore($flippedCells, $this->Session->read('aiside'));
            $score  = $result['score'] - $result['libertyPenalty'];
            $parentsTrace = $currentParent.'_'.$nextMove;

            if($currentDepth > 1)   //currentDepth == 1 means this is a leaf node.
                $this->buildTree($this->getGamecellMap($flippedCells), $currentDepth-1,
                                        $this->swapSides($currentSide), $parentsTrace);

            array_push($this->movesTree, array
                ('depth'=>$currentDepth,
                 'parentTrace'=>$parentsTrace,
                 'move'=>$nextMove,
                 'score'=>$score));
        }
    }
    if($currentDepth == 1)  //we have traversed all leaf nodes, time to quit.
        return;
}

因为我使用的是PHP + AJAX,我在PHP中调试的常规方法(在函数中回显一些东西)是行不通的。另外,当初始深度不超过3时,我仍然会对它的作用感到困惑...... 谁能帮我吗?任何建议都非常感谢,并提前多多感谢!

2 个答案:

答案 0 :(得分:1)

出于调试目的,我有这个功能:

function debug_array(){

        echo "<pre>";

        foreach(func_get_args() as $v){
            $v = Filter::htmlspecialchars($v, ENT_QUOTES, 'UTF-8');
        is_array($v) || is_object($v) ? print_r($v) : var_dump($v); 
        }
        echo "</pre>";
}

使用它很简单就可以将你想要的变量传递给debug_array()

debug_array($var1, $array, object, (bool)$test,...)

答案 1 :(得分:0)

您可以尝试通过回显出console.logs()来调试javascript,甚至可以尝试通过ajax请求的json输出中的注释(如果您正在评估它们),或使用http://www.firephp.org/之类的内容。 这样你就可以用javascript回调来调试它。 自发性臭虫是最难找到和修复的。看起来它现在对我来说工作正常。