如何在 PHP 中创建幻方?

发布于 2024-08-31 00:50:42 字数 604 浏览 5 评论 0原文

我想尝试用 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经验十多年前我就很快放弃了它。因此,我不太明白这段代码实际上在做什么。然而,我确实注意到,当您生成一个新的正方形时,它会按顺序显示数字 1-25(对于 5x5 的正方形),然后快速生成新的随机正方形。

I'd like to try my hand at creating a Magic Square in PHP (i.e. a grid of numbers that all add up to the same value), but I really don't know where to start. I know of the many methods that create magic square, such as starting "1" at a fixed position, then moving in a specific direction with each iteration. But that doesn't create a truly randomized Magic Square, which is what I'm aiming for.

I want to be able to generate an N-by-N Magic Square of N² numbers where each row and column adds up to N(N²+1)/2 (e.g. a 5x5 square where all rows/columns add up to 65 — the diagonals don't matter).

Can anybody provide a starting point? I don't want anybody to do the work for me, I just need to know how to start such a project?

I know of one generator, written in Java (http://www.dr-mikes-math-games-for-kids.com/how-to-make-a-magic-square.html) but the last Java experience I had was over 10 years ago before I quickly abandoned it. Therefore, I don't really understand what the code is actually doing. I did notice, however, that when you generate a new square, it shows the numbers 1-25 (for a 5x5 square), in order, before quickly generating a fresh randomized square.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

烏雲後面有陽光 2024-09-07 00:50:44

一个简单的 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

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

  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

上述步骤适用于幻方的任何阶!

A simple Java program to do this, can be easily rewritten in any language:

/*
* 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(); 

Algorithm:

  1. Form a Square Matrix writing numbers 1 to nxn in sequence. Here n is
    the order of the Magic Square, say 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. We are trying to identify the final Matrix from the above. Form two
    matrices, one for identifying the row and another to identify the
    column.
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

You will see the middle column of the first Matrix starts with 1 and
are in sequence. Columns on either side can be filled by subtracting
and adding 1. The second Matrix is a mirror image.

  1. Form the final Matrix by writing the number from initial Matrix in
    the corresponding row and column. For e.g 4, 3 (Step 2) = 18 (Step 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

The above steps are applicable for any order of the Magic Square!

不喜欢何必死缠烂打 2024-09-07 00:50:44

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

您引用的文章使用的方法是使用一些巧妙的数学,模拟退火。评论中没有解释实际的算法,我找不到任何详细信息的参考。我可以想象在不理解算法的情况下复制该算法,抄写现有的 Java - 实现的核心是很少的方法、数组和算术,几乎没有任何 Java 的聪明才智。

Wikipedia has several algorithms for generating magic squares, such as the siamese, if you please. But as you say that's not a truly random magic square. It does reference a genetic algorithm, wonder whether you could find more details about that?

The method used by your referenced article is using some clever maths, simulated annealing. The actual algorithm isn't explained in the comments and I can't find any references to the details. I could imagine replicating the algorithm without understanding it, transcribing the existing Java - the core of the implementation is very few methods, arrays and arithmentic hardly any Java cleverness.

轻拂→两袖风尘 2024-09-07 00:50:44

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

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

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

如果遇到问题,您将返回 false 并返回一行,并在开始时使用新的随机变量重做该行。

直到一切都恢复真实,你就有了一个 maqic 方块。

Sounds like you could solve this with recursion?

In my opinion: Start somewhere with a random number e.g. down right corner,
than you start a function solve row, which calls itself until all rows are solved and a function solveField which calls itself until all fields in a row are placed correctly. (fills an array)

solceField places 1. a random variable if there are no restrictions 2. the missing number to complete a row (you should have a check that it doesnt place to high too fast => sum may not be greater than the remaining fields in a row)

if you get somewhere stuck you return false and go back one row and redo the row with a new random variable at its start.

Until everything returns true and you have a maqic square.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文