3

我想尝试在 PHP 中创建一个魔方(即所有加起来相同值的数字网格),但我真的不知道从哪里开始。我知道许多创建幻方的方法,例如在固定位置开始“1”,然后在每次迭代中向特定方向移动。但这并不能创建一个真正随机的魔方,这正是我的目标。

我希望能够生成一个由 N² 数字组成的 N×N 魔方,其中每行和每列的总和为 N(N²+1)/2(例如,一个 5x5 的正方形,其中所有行/列的总和为 65 -对角线无关紧要)。

任何人都可以提供一个起点吗?我不想让任何人为我做这项工作,我只需要知道如何开始这样的项目?

我知道一个用 Java 编写的生成器(http://www.dr-mikes-math-games-for-kids.com/how-to-make-a-magic-square.html),但我最后一次体验 Java在我迅速放弃之前已经是 10 多年前了。因此,我真的不明白代码实际上在做什么。但是,我确实注意到,当您生成一个新正方形时,它会按顺序显示数字 1-25(对于 5x5 正方形),然后快速生成一个新的随机正方形。

4

3 回答 3

3

一个简单的 Java 程序可以做到这一点,可以很容易地用任何语言重写:

/*
* Magic Square
*/

int order = 5;

for (int row = 0; row < order; row++) {
    for (int col = 0; col < order; col++) {
        int rowMatrix = (((order + 1) / 2 + row + col) % order);
        int colMatrix = (((order + 1) / 2 + row + order - col - 1) %
order) + 1;
        System.out.print(((rowMatrix * order) + colMatrix) + "\t");
    }
    System.out.println(); 

算法:

  1. 形成一个按顺序写数字 1 到 nxn 的方阵。这里 n 是魔方的阶数,比如 5。
1 2 3 4 5  
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
  1. 我们试图从上面确定最终的矩阵。形成两个矩阵,一个用于标识行,另一个用于标识列。
4 5 1 2 3 3 2 1 5 4
5 1 2 3 4 4 3 2 1 5
1 2 3 4 5 5 4 3 2 1
2 3 4 5 1 1 5 4 3 2
3 4 5 1 2 2 1 5 4 3

您将看到第一个 Matrix 的中间列以 1 开头并按顺序排列。两边的列可以通过减加1来填充。第二个Matrix是一个镜像。

  1. 通过在相应的行和列中写入初始矩阵中的数字来形成最终矩阵。例如 4、3(步骤 2)= 18(步骤 1)
18 22 1 10 14
24 3 7 11 20
5 9 13 17 21
6 15 19 23 2
12 16 25 4 8

以上步骤适用于任何Magic Square的订单!

于 2010-05-11T09:16:38.867 回答
2

维基百科有几种生成幻方的算法,比如siamese,如果你愿意的话。但正如你所说,这不是一个真正的随机幻方。它确实引用了遗传算法,想知道您是否可以找到更多详细信息?

您引用的文章使用的方法是使用一些聪明的数学,模拟退火。评论中没有解释实际的算法,我找不到任何对细节的引用。我可以想象在不理解它的情况下复制算法,转录现有的 Java - 实现的核心是很少的方法、数组和算术几乎没有任何 Java 聪明。

于 2010-05-05T04:33:49.860 回答
0

听起来你可以用递归解决这个问题?

在我看来:从某个随机数开始,例如右下角,然后开始一个函数求解行,它会调用自身,直到所有行都被求解,以及一个函数solveField,它调用自身,直到正确放置一行中的所有字段。(填充一个数组)

solceField 放置 1. 如果没有限制,则放置一个随机变量 2. 完成一行的缺失数字(您应该检查它不会太快放置太高 => 总和可能不会大于一行中的其余字段)

如果您遇到卡住的地方,则返回 false 并返回一行并在开始时使用新的随机变量重做该行。

直到一切都返回 true 并且你有一个 maqic 正方形。

于 2010-05-05T08:17:45.027 回答