3

PHP で魔方陣 (つまり、合計すると同じ値になる数字のグリッド) を作成してみたいのですが、どこから始めればよいかわかりません。固定位置で「1」を開始し、反復ごとに特定の方向に移動するなど、魔方陣を作成する多くの方法を知っています。しかし、それは私が目指している真にランダム化された魔方陣を作成しません.

各行と列の合計が N(N²+1)/2 になる N² 数の N 行 N 列の魔方陣 (たとえば、すべての行/列の合計が 65 になる 5x5 の正方形) を生成できるようにしたいと考えています。対角線は関係ありません)。

誰でも出発点を提供できますか? 誰にも仕事を任せたくないのですが、そのようなプロジェクトを開始する方法を知りたいだけですか?

私は Java で書かれた 1 つのジェネレーター ( 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からn×nまでの数字を順番に書いて正方行列を作ります。ここで、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. 上記から最終的なマトリックスを特定しようとしています。1 つは行を識別するため、もう 1 つは列を識別するための 2 つの行列を作成します。
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 を減算および加算することで埋めることができます。2 番目の行列は鏡像です。

  1. 対応する行と列に最初の Matrix からの数を書き込んで、最終的な Matrix を形成します。たとえば、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

上記の手順は、魔方陣のどの順序にも適用できます。

于 2010-05-11T09:16:38.867 に答える
2

ウィキペディアには、siameseなど、魔方陣を生成するためのアルゴリズムがいくつかあります。しかし、あなたが言うように、それは本当にランダムな魔方陣ではありません. それは遺伝的アルゴリズムを参照していますが、それについての詳細を見つけることができるかどうか疑問に思いますか?

参照された記事で使用されている方法は、いくつかの巧妙な数学、シミュレーテッド アニーリングを使用しています。実際のアルゴリズムはコメントで説明されておらず、詳細への参照が見つかりません。アルゴリズムを理解せずに複製し、既存の Java を書き写すことを想像できます。実装の中核は、メソッド、配列、および算術演算であり、Java の巧妙さはほとんどありません。

于 2010-05-05T04:33:49.860 に答える
0

これを再帰で解決できるように聞こえますか?

私の意見では、すべての行が解決されるまで自分自身を呼び出す関数 solve row と、行内のすべてのフィールドが正しく配置されるまで自分自身を呼び出す関数 solveField を開始するよりも、右隅などの乱数でどこかから始めます。(配列を埋めます)

solceField は、1. 制限がない場合はランダム変数を配置します。 2. 行を完成させるための欠落数 (配置が速すぎないことを確認する必要があります => 合計が行の残りのフィールドよりも大きくならない可能性があります)。

どこかで行き詰まった場合は、false を返し、1 行前に戻り、最初に新しいランダム変数を使用して行をやり直します。

すべてが true を返し、魔方陣が得られるまで。

于 2010-05-05T08:17:45.027 に答える