【问题标题】:Brute force magic squares蛮力魔方
【发布时间】:2011-02-07 23:10:07
【问题描述】:

基本上,我有一个 3 x 3 的网格,其中填充了两位数字 00 - 99。其中一些数字作为输入给出,其余的未知。关于如何在 C 中使用蛮力解决此类问题有什么建议?

编辑:抱歉,我忘记了部分问题。每行和每列和对角线必须加起来相同的数字。我不想要任何代码,只是一些开始使用算法的想法

【问题讨论】:

  • 解决什么问题?
  • 是幻方问题吗?
  • 在不知道它是怎么回事的情况下收藏一个问题有多酷?
  • 要找到一个蛮力解决方案,实际上并不需要知道问题所在(从我们的角度来看)。答案总是一样的:尝试所有组合,直到找到解决问题的解决方案。
  • 如果你不想要代码,为什么要标记 c?

标签: algorithm brute-force magic-square


【解决方案1】:

有一个简单的递归解决方案可以解决您的问题,这是一种称为回溯的蛮力示例(google that)。

递归函数(例如,fill_next)找到下一个具有未知值的单元格。如果没有这样的单元格,它会检查正方形以查看它是否符合要求(总和是否正确),如果是,则打印正方形作为解决方案;然后它返回。如果有一个单元格具有未知值,它会循环,依次尝试该单元格的每个值 0 到 99,然后递归调用自身以填充下一个未知单元格。

如何到达下一个值未知的单元格:您可以简单地将下一个单元格的编号传递给 find_next 以开始查看;您可以通过调用 fill_next(0) 来开始整个过程​​。单元格编号为 0 到 8,因为您有 9 个单元格。如果您将正方形存储在二维数组中,只需使用 num%3 和 num/3 作为索引。

只需给你几行代码就可以更容易地描述它,但你说你不想要那样。

【讨论】:

    【解决方案2】:

    幻方实际上是一个(简单)联立方程系统。您可以通过转换为矩阵并使用Gaussian elimination 来解决这些问题,这是蛮力但同时也相当优雅。如果解决方案不是唯一的,那么您至少会减少对解决方案的限制,这应该会使解决方案变得更加简单。

    【讨论】:

    • 这不是“蛮力”,因为该术语通常(甚至不常见)被理解。这当然是解决问题的一种更有效和更有效的方法,但这不是 OP 所要求的。
    • @Jim:您不想将“真正的”蛮力应用于幻方(即扫描所有可能性并逐一查看,如果它们是解决方案)作为搜索空间为 100^9(== 10^18;使用当前技术的许多 CPU 年),因此完全不切实际。
    • 要扩展“许多 CPU 年”,一个现代 CPU 无法在 1ns 内搜索一个组合。您需要一个集群,可能是一个大型集群,才能获得这样的搜索率,即便如此,您预计解决问题的时间大约是 16 年。 (上限 - 1Gs - 略低于 32 年;假设解决方案是唯一的,预期的搜索时间大约是这个时间的一半。)
    • 请阅读问题陈述——一些值已经填好了。“你”想要做什么是无关紧要的——这就是 OP(或 OP 的导师)要求的。
    【解决方案3】:

    你的问题是什么?你想找出每个数字是什么吗?这些数字必须满足他们的任何标准吗?如果是这样,只需猜测每个可能的数字??直到组合符合标准为止。

    【讨论】:

    • 抱歉,我忘记了部分问题。每行和每列和对角线必须加起来相同的数字。
    • 据我了解,“只需猜测每个可能的数字??”是 OP 要求解决的问题。检查生成的正方形是否是幻方更不言而喻。
    【解决方案4】:

    3x3 网格听起来像二维数组。

    JS中的一些示例代码:

    var a=[
        [ 11, 12, 13 ],
        [ 21, 22, 23 ],
        [ 31, 32, 33 ]
    ];
    for(var r=0; r<a.length; r++)
        for(var c=0; c<a[r].length; c++)
            console.log(r+','+c+' = '+a[r]+','+a[r][c]);
    

    a - 3x3 网格数组(数组数组) r - 当前行迭代 c - 当前列迭代

    可选地,a.lengtha[r].length 都可以是 3 的常量(在您的情况下)。

    【讨论】:

    • 这会打印出一个网格,但这不是 OP 的要求。
    • @Jim - 这是“蛮力”网格,正是 OP 想要的,不同的是 OP 没有说他想用它做什么,所以我选择打印出来.
    • @Christian 不,这不是 OP 想要的。 OP 想要知道如何解决一些值已知而一些未知的幻方。
    • @Jim - 如果他的 OP 在他的问题中足够清楚,willytate 就不会这么问了......
    • @Christian 我没说他很清楚,但你是使用“完全”这个词的人,你肯定漏掉了一些东西。
    【解决方案5】:

    魔方问题的蛮力非常简单。

    1. 遍历每一行并计算每一行的总和(保持 i 不变,j++)(3 个总和)
    2. 遍历每一列并计算每一列的总和(保持 j 不变,i++)(3 个总和)
    3. 迭代两条对角线并计算总和(i++,j++,使得 i 等于 j)(2 个总和)

    如果总和与您在任何时候计算的第一个总和不同,那么您就完成了。如果所有的和都相等,那么你就找到了魔方。

    【讨论】:

    • 这确定了一个填充的正方形是否是一个幻方,但是OP正在询问如何填充正方形以找到所有解决方案。
    • 哦,是的!好吧,蛮力将尝试丢失位置中的每个数字组合。如果缺少 3 个单元格,请尝试 0-0-0,然后运行我上面描述的算法。然后尝试 0-0-1,然后再次运行算法,依此类推,直到 99-99-99。这是假设幻数是未知的。
    • 当您说“尝试 0-0-0 ... 然后尝试 0-0-1 等”时你只是在重复这个问题,而不是回答它。请参阅上面的答案,它提供了一种算法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-24
    相关资源
    最近更新 更多