第19講 .NETによるマルチスレッドプログラミング
第2話 マルチスレッド解答例??
今日いろいろ研究を重ねましたが、
出来の悪いプログラムしかできませんでした。

素数探索のときは、表示に時間がかかりルートスレッドの方が早く終わってしまうことはありませんでしたが、
魔方陣の場合は立ち上げたスレッドの方が時間がかかり、ルートが終了してしまい表示させるのが難しいのです。
工夫すれば、うまくいくんでしょうが、だめでした。。・゚゚・(≧д≦)・゚゚・。エーン!!。

仕方なく、魔方陣数だけ表示するサンプルにします。
#include<iostream>
#include<process.h>
using namespace std;
using namespace System;
void f(void *t);
void f0();
void f1(int t,int g);
void f2(int t);
int n,cn1,cn2,cn3,cn4;
int m1[10][10],m2[10][10],m3[10][10],m4[10][10],a1[2000][10][10],a2[2000][10][10],a3[2000][10][10],a4[2000][10][10];
int x[100],y[100];
int main(){

  cout<<"何次魔方陣を作成させるのかキーボードから入力してください。尚、4つの分類すべてが表示されたら×ボタンを押して終了してください。"<<endl;
  cout<<"次数=";
  scanf("%d",&n);
  
  f0();
  cn1=0;cn2=0;cn3=0;cn4=0;
  _beginthread(f, 0, (void *)1);
  _beginthread(f, 0, (void *)2);
  _beginthread(f, 0, (void *)3);
  _beginthread(f, 0, (void *)4);

  for(int i=0;i<4300000000;i++); 
             /*
               ルートスレッドを待機させるために無駄打ちをしている。実験でどんぴしゃりの値を見つけよう努力したのですが
               うまくいきませんでした。これが見つかればルートの方ですべての魔方陣を表示できるのですが。。・°°・(((p(≧□≦)q)))・°°・。ウワーン!!
             */
  /*
  int i,j,c[10][10];
  for(i=0;i<n*n;i++){
    c[y[i]][x[i]]=i;
  }
  for(i=0;i<n;i++){
    for(j=0;j<n;j++){
      if(c[i][j]<10)cout<<" "<<c[i][j]<<" ";
      if(c[i][j]>=10)cout<<c[i][j]<<" ";
    }
    cout<<endl;
  }
  */
}
void f0(){
  int i,j,c=0;
  int b[10][10];
  for(i=0;i<n;i++){
    for(j=0;j<n;j++){
      b[i][j]=-1;
    }
  }
  for(i=0;i<n;i++){
    b[i][i]=i;
  }
  c=n-1;
  for(i=0;i<n;i++){
    if(b[i][n-1-i]==-1){
      c++;
      b[i][n-1-i]=c;
    }
  }
  for(i=0;i<n;i++){
    for(j=0;j<n;j++){
      if(b[i][j]==-1){
        c++;
        b[i][j]=c;
      }
    }
  }
  for(i=0;i<n;i++){
    for(j=0;j<n;j++){
      x[b[i][j]]=j;
      y[b[i][j]]=i;
    }
  }
}
void f(void *t){
  if(t==(void *)1){
    DateTime^ hj=DateTime::Now;
    f1(1,0);
    cout<<"分類1の"<<n<<"次魔方陣が"<<cn1<<"個できました。"<<endl;
    DateTime^ ow=DateTime::Now;
    TimeSpan sa=ow->Subtract(*hj);
    cout<<"計算時間は"<<sa.TotalSeconds<<"秒です。"<<endl;
  }
  if(t==(void *)2){
    DateTime^ hj=DateTime::Now;
    f1(2,0);
    cout<<"分類2の"<<n<<"次魔方陣が"<<cn2<<"個できました。"<<endl;
    DateTime^ ow=DateTime::Now;
    TimeSpan sa=ow->Subtract(*hj);
    cout<<"計算時間は"<<sa.TotalSeconds<<"秒です。"<<endl;
  }
  if(t==(void *)3){
    DateTime^ hj=DateTime::Now;
    f1(3,0);
    cout<<"分類3の"<<n<<"次魔方陣が"<<cn3<<"個できました。"<<endl;
    DateTime^ ow=DateTime::Now;
    TimeSpan sa=ow->Subtract(*hj);
    cout<<"計算時間は"<<sa.TotalSeconds<<"秒です。"<<endl;
  }
  if(t==(void *)4){
    DateTime^ hj=DateTime::Now;
    f1(4,0);
    cout<<"分類4の"<<n<<"次魔方陣が"<<cn4<<"個できました。"<<endl;
    DateTime^ ow=DateTime::Now;
    TimeSpan sa=ow->Subtract(*hj);
    cout<<"計算時間は"<<sa.TotalSeconds<<"秒です。"<<endl;
  }
}
void f1(int t,int g){
  register char i,j;
  char h,w,ii,iii;
  if(t==1){
    for(i=1;i<n*n+1;i++){
      if(g==0 && i>n*n/4)return;
      m1[y[g]][x[g]]=i;
      h=1;
      if(g>0){
        for(j=0;j<g;j++){
          if(m1[y[g]][x[g]]==m1[y[j]][x[j]]){
            h=0;
            break;
          }
        }
      }
      if(h==1 && y[g]==n-1 && x[g]==n-1){
        w=0;
        for(j=0;j<n;j++){
          w+=m1[j][j];
        }
        if(w!=n*(n*n+1)/2)h=0;
      }
      if(h==1 && y[g]==n-1 && x[g]==0){
        w=0;
        for(j=0;j<n;j++){
          w+=m1[n-1-j][j];
        }
        if(w!=n*(n*n+1)/2)h=0;
      }
      if(h==1 && y[g]==0 && x[g]==n-2){
        w=0;
        for(j=0;j<n;j++){
          w+=m1[y[g]][j];
        }
        if(w!=n*(n*n+1)/2)h=0;
      }
      if(h==1 && g>n && x[g]==n-1){
        w=0;
        for(j=0;j<n;j++){
          w+=m1[y[g]][j];
        }
        if(w!=n*(n*n+1)/2)h=0;
      }
      if(h==1 && y[g]==n-2 && x[g]==0){
        w=0;
        for(j=0;j<n;j++){
          w+=m1[j][x[g]];
        }
        if(w!=n*(n*n+1)/2)h=0;
      }
      if(h==1 && g>2*n && y[g]==n-1){
        w=0;
        for(j=0;j<n;j++){
          w+=m1[j][x[g]];
        }
        if(w!=n*(n*n+1)/2)h=0;
      }
      
      if(h==1){
        if(g+1<n*n){
          f1(t,g+1);
         }
         else{
          f2(t);
          cn1++;
          //if(cn==100)break;
        }
      }
      //if(cn==100)break;
    }
    m1[y[g]][x[g]]=0;
  }
  if(t==2){
    for(i=1;i<n*n+1;i++){
      if(g==0){
        if(i==1)i=n*n/4+1;
        if(i>n*n/2)return;
      }
      m2[y[g]][x[g]]=i;
      h=1;
      if(g>0){
        for(j=0;j<g;j++){
          if(m2[y[g]][x[g]]==m2[y[j]][x[j]]){
            h=0;
            break;
          }
        }
      }
      if(h==1 && y[g]==n-1 && x[g]==n-1){
        w=0;
        for(j=0;j<n;j++){
          w+=m2[j][j];
        }
        if(w!=n*(n*n+1)/2)h=0;
      }
      if(h==1 && y[g]==n-1 && x[g]==0){
        w=0;
        for(j=0;j<n;j++){
          w+=m2[n-1-j][j];
        }
        if(w!=n*(n*n+1)/2)h=0;
      }
      if(h==1 && y[g]==0 && x[g]==n-2){
        w=0;
        for(j=0;j<n;j++){
          w+=m2[y[g]][j];
        }
        if(w!=n*(n*n+1)/2)h=0;
      }
      if(h==1 && g>n && x[g]==n-1){
        w=0;
        for(j=0;j<n;j++){
          w+=m2[y[g]][j];
        }
        if(w!=n*(n*n+1)/2)h=0;
      }
      if(h==1 && y[g]==n-2 && x[g]==0){
        w=0;
        for(j=0;j<n;j++){
          w+=m2[j][x[g]];
        }
        if(w!=n*(n*n+1)/2)h=0;
      }
      if(h==1 && g>2*n && y[g]==n-1){
        w=0;
        for(j=0;j<n;j++){
          w+=m2[j][x[g]];
        }
        if(w!=n*(n*n+1)/2)h=0;
      }

      if(h==1){
        if(g+1<n*n){
          f1(t,g+1);
         }
         else{
          f2(t);
          cn2++;
          //if(cn==100)break;
        }
      }
      //if(cn==100)break;
    }
    m2[y[g]][x[g]]=0;
  }
  if(t==3){
    for(i=1;i<n*n+1;i++){
      if(g==0){
        if(i==1)i=n*n/2+1;
        if(i>3*n*n/4)return;
      }
      m3[y[g]][x[g]]=i;
      h=1;
      if(g>0){
        for(j=0;j<g;j++){
          if(m3[y[g]][x[g]]==m3[y[j]][x[j]]){
            h=0;
            break;
          }
        }
      }
      if(h==1 && y[g]==n-1 && x[g]==n-1){
        w=0;
        for(j=0;j<n;j++){
          w+=m3[j][j];
        }
        if(w!=n*(n*n+1)/2)h=0;
      }
      if(h==1 && y[g]==n-1 && x[g]==0){
        w=0;
        for(j=0;j<n;j++){
          w+=m3[n-1-j][j];
        }
        if(w!=n*(n*n+1)/2)h=0;
      }
      if(h==1 && y[g]==0 && x[g]==n-2){
        w=0;
        for(j=0;j<n;j++){
          w+=m3[y[g]][j];
        }
        if(w!=n*(n*n+1)/2)h=0;
      }
      if(h==1 && g>n && x[g]==n-1){
        w=0;
        for(j=0;j<n;j++){
          w+=m3[y[g]][j];
        }
        if(w!=n*(n*n+1)/2)h=0;
      }
      if(h==1 && y[g]==n-2 && x[g]==0){
        w=0;
        for(j=0;j<n;j++){
          w+=m3[j][x[g]];
        }
        if(w!=n*(n*n+1)/2)h=0;
      }
      if(h==1 && g>2*n && y[g]==n-1){
        w=0;
        for(j=0;j<n;j++){
          w+=m3[j][x[g]];
        }
        if(w!=n*(n*n+1)/2)h=0;
      }

      if(h==1){
        if(g+1<n*n){
          f1(t,g+1);
         }
         else{
          f2(t);
          cn3++;
          //if(cn==100)break;
        }
      }
      //if(cn==100)break;
    }
    m3[y[g]][x[g]]=0;
  }
  if(t==4){
    for(i=1;i<n*n+1;i++){
      if(g==0){
        if(i==1)i=3*n*n/4+1;
      }
      m4[y[g]][x[g]]=i;
      h=1;
      if(g>0){
        for(j=0;j<g;j++){
          if(m4[y[g]][x[g]]==m4[y[j]][x[j]]){
            h=0;
            break;
          }
        }
      }
      if(h==1 && y[g]==n-1 && x[g]==n-1){
        w=0;
        for(j=0;j<n;j++){
          w+=m4[j][j];
        }
        if(w!=n*(n*n+1)/2)h=0;
      }
      if(h==1 && y[g]==n-1 && x[g]==0){
        w=0;
        for(j=0;j<n;j++){
          w+=m4[n-1-j][j];
        }
        if(w!=n*(n*n+1)/2)h=0;
      }
      if(h==1 && y[g]==0 && x[g]==n-2){
        w=0;
        for(j=0;j<n;j++){
          w+=m4[y[g]][j];
        }
        if(w!=n*(n*n+1)/2)h=0;
      }
      if(h==1 && g>n && x[g]==n-1){
        w=0;
        for(j=0;j<n;j++){
          w+=m4[y[g]][j];
        }
        if(w!=n*(n*n+1)/2)h=0;
      }
      if(h==1 && y[g]==n-2 && x[g]==0){
        w=0;
        for(j=0;j<n;j++){
          w+=m4[j][x[g]];
        }
        if(w!=n*(n*n+1)/2)h=0;
      }
      if(h==1 && g>2*n && y[g]==n-1){
        w=0;
        for(j=0;j<n;j++){
          w+=m4[j][x[g]];
        }
        if(w!=n*(n*n+1)/2)h=0;
      }

      if(h==1){
        if(g+1<n*n){
          f1(t,g+1);
         }
         else{
          f2(t);
          cn4++;
          //if(cn==100)break;
        }
      }
      //if(cn==100)break;
    }
    m4[y[g]][x[g]]=0;
  }

}
void f2(int t){
  int i,j;
  if(t==1){
    for(i=0;i<n;i++){
      for(j=0;j<n;j++){
        a1[cn1][i][j]=m1[i][j];
      }
    }
  }

  if(t==2){
    for(i=0;i<n;i++){
      for(j=0;j<n;j++){
        a2[cn2][i][j]=m2[i][j];
      }
    }
  }
  if(t==3){
    for(i=0;i<n;i++){
      for(j=0;j<n;j++){
        a3[cn3][i][j]=m3[i][j];
      }
    }
  }
  if(t==4){
    for(i=0;i<n;i++){
      for(j=0;j<n;j++){
        a4[cn4][i][j]=m4[i][j];
      }
    }
  }
}
実行結果例
入門
一応
C言語
CPU使用率100%は実現できているし、
コンソールに魔方陣を表示していないのでかなり有利とはいえ、
時間比で21/48にはなっています。
今回のプログラムの問題点を.NETのgcnew Threadを使うことによって解消します。

gcnew ThreadにはJoin()という待機させる関数があるのです。

そしてスレッドを生成するには、
Thread^ 変数名=gcnew Thread(gcnew ThreadStart(関数名));
を使います。それぞれのスレッドをスタートさせるには、
変数名->Start();
とします。これを使って改良を試みましょう。







第1話へ 第3話へ

戻る

C言語 C++講義第1部へ
VB講義へ
VB講義基礎へ

vc++講義へ第1部へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)