第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;

実験結果
a
乱数を組み込む前が、
w
ですから、
反って遅くなっているではありませんか。
ですが、実はちょっと改良すると、
s

と約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個生成できるようにして下さい。
さて、今回の魔方陣自動生成ソフトを
対角線法魔方陣自動生成ソフトと名付けることにしましょう。
次講では、対角線法をさらに改良してさらなる高速化に挑戦します。
その方法は、末項確定法です。

第10話へ 第20講第1話へ

a

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

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