第19講 座標の工夫による魔方陣自動生成ソフトの高速化
第11話 シード値
コード主要部分再掲
long f(int *k,int **x,int n,long cn,int g,int *p,int *q){
int i,j,s,t,w,v;
s=q[g];
t=p[g];
int ii,iii;
ii=rand()%(n*n);
for(iii=1;iii<n*n+1;iii++){
i=(iii+ii)%(n*n)+1;
x[s][t]=i;
実験結果
乱数を組み込む前が、
ですから、
反って遅くなっているではありませんか。
ですが、実はちょっと改良すると、
と約6倍速くなります。
何をしたかといいますと、
long f(int *k,int **x,int n,long cn,int g,int *p,int *q){
int i,j,s,t,w,v;
s=q[g];
t=p[g];
int ii,iii;
srand(14);
ii=rand()%(n*n);
for(iii=1;iii<n*n+1;iii++){
i=(iii+ii)%(n*n)+1;
x[s][t]=i;
参考ダウンロードファイル
ピンクを加えただけです。
つまり、シード値を14に指定しただけです。
srand(*)の*をシード値といい、
シード値の値によって乱数系列が変わるのでした。
では、シード値14のときに速くなることはどのようにして分かったのでしょうか。
それは、次の乱数系列最適実験によってです。
#include<iostream>
#include <time.h>
using namespace std;
long f(int *k,int **x,int n,long cn,int g,int *p,int *q);
void ts(int **x,int n,int *p,int *q);
void h(int **x,int n);
void syokika(int n,int *k);
void zh(int n,int *p,int *q);
int c;
void main(){
int n,ckr;
//cout<<"何次魔方陣を生成しますか?"<<endl;
//scanf("%d",&n);
n=5;
int **x=(int **)malloc(sizeof(int)*n);
for(char i=0;i<n;i++)x[i]=(int *)malloc(sizeof(int)*n);
int *k=(int *)malloc(sizeof(int)*n*n);
int p[100],q[100];
cout<<endl;
clock_t hj,ow,sa,sam=10000000; //clock_t型の宣言、プログラム開始時間を取得するための変数
for(c=4;c<35;c++){
hj=clock();
syokika(n,k);
zh(n,p,q);
//ts(x,n,p,q);
cout<<n<<"次魔方陣が"<<f(k,x,n,0,0,p,q)<<"個生成されました。"<<endl;
ow=clock();
sa=ow-hj;
if(sa<sam){
sam=sa;
ckr=c;
}
cout<<"魔方陣生成にかかった時間は"<<(double)sa/1000<<"秒です。"<<endl;
}
cout<<ckr<<" "<<(double)sam/1000<<endl;
}
void ts(int **x,int n,int *p,int *q){
・・・・・
}
void zh(int n,int *p,int *q){
・・・・・}
}
void syokika(int n,int *k){
for(int i=0;i<n*n;i++)k[i]=0;
}
long f(int *k,int **x,int n,long cn,int g,int *p,int *q){
int i,j,s,t,w,v;
s=q[g];
t=p[g];
int ii,iii;
srand(c);
ii=rand()%(n*n);
for(iii=1;iii<n*n+1;iii++){
i=(iii+ii)%(n*n)+1;
x[s][t]=i;
・・・・・
}
実験の範囲が、4から35になっていますが、
始まりについては、手動で4の方が0,1,2,3の場合をより速いことが分かっていて、
終わりは時間を考えてです。
範囲ともっと広げればより最適なシード値を見つけられます。
皆さん、探索範囲を広げ、
n=6; と変更して、数秒程度100個生成できるようにして下さい。
さて、今回の魔方陣自動生成ソフトを
対角線法魔方陣自動生成ソフトと名付けることにしましょう。
次講では、対角線法をさらに改良してさらなる高速化に挑戦します。
その方法は、末項確定法です。