第24講 特殊種法で魔方陣を超高速に自動生成する
第10話 直交させるためのヒント


5 3 2 1 4
3 4 1 5 2
1 2 3 4 5
4 1 5 2 3
2 5 4 3 1


1 5 4 2 3
3 4 1 5 2
5 3 2 4 1
2 1 5 3 4
4 2 3 1 5

の直交性を確認するには碁盤

 1  2  3  4  5

を用意して、そこに碁石を置いていきます。

5 3 2 1 4
3 4 1 5 2
1 2 3 4 5
4 1 5 2 3
2 5 4 3 1


1 5 4 2 3
3 4 1 5 2
5 3 2 4 1
2 1 5 3 4
4 2 3 1 5

例えば、最初に組み合わせ(
(以下、色の対応に注意して読んでください。

5

対応しますし、

1

に対応しています。)
に碁石を置くと、

 1  2  3  4  5

となります。そして、次ぎに

5 3 2 1 4
3 4 1 5 2
1 2 3 4 5
4 1 5 2 3
2 5 4 3 1


1 5 4 2 3
3 4 1 5 2
5 3 2 4 1
2 1 5 3 4
4 2 3 1 5

の組み合わせ()に碁石を置いて、

 1  2  3  4  5

以下同様に(),(),()と置くと

 1  2  3  4  5

となっていきます。このように置いていって、

 1  2  3  4  5

と1つずつ置ければ、直交ですし、
同じところ2つ以上碁石が重なれば直交しません。
尚、再帰的関数が1つ手前の再帰的関数に帰るときには、
置いた碁石を取り去ることを忘れないで下さい。
もちろん、すでに置いてあった(=1つ以上手前の再帰的関数が碁石を置いた)
場合には、取り去ってはいけませんね。


では、以上を参考にして魔方陣特殊種法による自動生成ソフト完成させましょう。
f
g

なんと、5次魔方陣57600個が3.387秒で出来ました。
1個あたり0.0000588020833333333秒という信じられない高速化に
成功しています。
尚、碁盤に対応する配列を付け加えるため、

#include<iostream>
using namespace std;
int f1(int g,int m1[10][10],int m2[10][10],int a[10][10],int n,int* p,int* q,int cn);
int f2(int g,int m1[10][10],int m2[10][10],int a[10][10],int n,int* p,int* q,int cn);
void h(int m1[10][10],int m2[10][10],int n);
void zh(int n,int *p,int *q);
void sy(int m1[10][10],int n);
void sy1(int m2[10][10]
,int a[10][10],int n);
void main(){
   int m1[10][10],m2[10][10],a[10][10],n,t=0;
    ・・・
    ・・・
   cout<<n<<"次魔方陣種が"<<endl<<f1(0,m1,m2,a,n,p,q,0)<<"個できました。"<<endl;;
   cout<<"プロジェクト終了"<<endl;
}
void zh(int n,int *p,int *q){
    ・・・
    ・・・
}
int f1(int g,int m1[10][10],int m2[10][10],int a[10][10],int n,int* p,int* q,int cn){  
    ・・・
    ・・・
     if(g+1<n*n){
        cn=f1(g+1,m1,m2,a,n,p,q,cn);
     }
     else{
        cn=f2(0,m1,m2,a,n,p,q,cn);
     }
     tobi:;
   }
   return(cn);
}
int f2(int g,int m1[10][10],int m2[10][10],int a[10][10],int n,int* p,int* q,int cn){
    ・・・
    ・・・
     if(g+1<n*n){
        cn=f2(g+1,m1,m2
,a,n,p,q,cn);
        //if(cn==100)return(cn);
     }
     else{
        h(m1,m2,n);
        cout<<endl<<endl;
        //if(cn==100)return(cn);
        cn++;
     }
     tobi:;
   }
   return(cn);
}
void h(int m1[10][10],int m2[10][10],int n){
    ・・・
    ・・・
}
と変更しておきましょう。






第9話へ 第11話へ

a

eclipse c++ 入門講義第1部へ

eclipse c++ 入門講義第2部へ


魔方陣 数独で学ぶ VBA 入門
数独のシンプルな解き方・簡単な解法の研究
VB講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)
初心者のための VC++による C言語 C++ 入門 基礎から応用まで第1部
eclipse java 入門
java 入門 サイト 基礎から応用まで
VC++ C言語 C++ 入門 初心者 基礎から応用まで
本サイトトップへ