【问题标题】:Optimize shuffled array - do I need to go through the whole array?优化洗牌数组 - 我需要遍历整个数组吗?
【发布时间】:2020-05-30 21:47:33
【问题描述】:

我将尝试解释我的问题。我正在尝试在 PHP 中创建一个国际象棋引擎(只是为了好玩:-))代码中的整数只返回有效的移动(为了简单起见 - 在实际代码中,它的对象和移动模式取决于它是关于哪一块)


我正在寻找一种有效搜索数组的方法。有效是指尽可能快。看看我在下面代码中的评论“是否可以在不遍历所有 1000 个值的情况下跳出循环?”我希望 cmets 会尝试解释我想要实现的目标。我只是在寻找优化以下代码的想法,而不是完整的代码:-)


//This is for demonstrating
//1000 values to go through
$moves_maybe_valid = range(1,1000);
shuffle($moves_maybe_valid);

//Go through possible values
$move_checked = [];
$nr=0;
foreach($moves_maybe_valid as $mmv) {
    $move_is_valid = check_move($mmv);

    //Check if not in checked array
    if ($move_is_valid === false && !in_array($mmv, $move_checked)) {

        //Add to checked move array
        $move_checked[] = $mmv;
    }

    //IS it possible to break out of loop without 
    //going through all 1000 values?
    //When all valid moves are true I want to break here
    //but I don't know when that is.

}

//for demonstration purpose only
//numbers (5,6) that returns true are unknown until an
//an actual check is done in this function
function check_move($nr) {
    if ($nr == 5 || $nr == 6) {
        return true;
    }
    return false;
}

如果我说我会从一开始就生成有效的移动(基于下面的 cmets)

$valid_moves = [5,6];

摆脱循环的最佳方法是什么?

【问题讨论】:

  • foreach(range(1,1000) as $nr) $moves_maybe_valid[] = $nr; 只是$moves_maybe_valid = range(1, 1000); 哈哈:P
  • @RoboRobok .- 哈哈。真的!很抱歉 :-) LOL
  • 你的意思是,break;?
  • 我无法想象如果你没有检查移动是否有效,你怎么会知道没有更多的有效移动。你为什么不首先生成有效的移动?
  • 一个优化是你可能不需要检查in_array。除非您的原始列表中有重复项,否则您不可能多次添加相同的动作。 in_array 很昂贵,从 O(n) 到 O(n^2)

标签: php performance random


【解决方案1】:

在正常情况下,您可能会遇到的最大有效移动数约为 100。如果您有 9 个皇后,可能会达到 200 个。不过,1000 太大了.

生成有效动作列表应该意味着您甚至不需要检查它们是否有效。但是,我想你正在生成一个所有组合的列表,即使它们涉及传递另一块棋子、用你自己的棋子降落在一个正方形上,或者降落在棋盘域之外。

我会说,在您的第一代进行这些检查:

  • 对于每个棋子,检查 4 个可能的移动并存储有效的移动

  • 对于每个城堡或主教,按顺序检查 14 个可能,从 在棋子位置,向 4 个方向走,直到击中 无效空间(击中你自己的棋子意味着你走得太远了。 击中对手的棋子意味着你已经击中了最后可能)

  • 对于皇后,与城堡或主教相同,但 8 个方向而不是 4 个
  • 为骑士检查 8 个可能的动作是否有效
  • 对于国王,检查 8 有效性的可能举措
  • 检查两个城堡中的任何一个是否移动 有可能

对于每一个动作,您还需要确保它不会让您受到控制。该功能可能可以优化,因此您只能从王者的位置向外看。

一旦你完成了所有棋子,最多 16 个棋子,你的动作列表应该只包含有效的动作。

事情变得昂贵的地方是您的前瞻性。您想模拟未来多少步?您如何衡量每一步的价值/风险?

然后是个人资料。您需要一个好的采样分析器来优化和找到您的热点。注意像in_array 这样昂贵的便利功能,如果可以的话,尽量避免。循环中的循环会降低性能。

【讨论】:

    猜你喜欢
    • 2012-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-10
    • 2015-04-15
    • 1970-01-01
    相关资源
    最近更新 更多