第24講 数独解答作成の作成
第6話 BackgroundWorkerによる高速化(9次の場合) 

#pragma once
#include<stdlib.h>
int n;
int a1[10][10],a2[10][10],a3[10][10],a4[10][10],as1[100][10][10],as2[100][10][10],as3[100][10][10],as4[100][10][10];
int x[100],y[100];
int s1,s2,s3,s4;
namespace 9次数独作成4スレッド(BackgrouンdWorker版) {
           ・
           ・
           ・
#pragma endregion
  private: System::Void backgroundWorker1_DoWork(System::Object^ sender, System::ComponentModel::DoWorkEventArgs^ e) {
          s1=0;
          f1(0);
        }
  private: System::Void backgroundWorker1_RunWorkerCompleted(System::Object^ sender, System::ComponentModel::RunWorkerCompletedEventArgs^ e) {
          array<String^>^ w=gcnew array<String^>(14);
          char i,j,k,l;
          for(i=0;i<25;i++){
            for(j=0;j<n;j++){
              if(j%3==0){
                 for(k=0;k<13;k++)w[k]=L"*";
                    dataGridView1->Rows->Add(w);
                 }
                 l=0;
                 for(k=0;k<n;k++){
                   if(k%3==0){
                     w[k+l]=L"*";
                     l++;
                   }
                   w[k+l]=(as1[i][j][k]).ToString();
                 }
                 w[k+l]=L"*";
                 dataGridView1->Rows->Add(w);
              }
              for(k=0;k<13;k++)w[k]=L"*";
              dataGridView1->Rows->Add(w);
              for(j=0;j<13;j++)w[j]=L"";
              dataGridView1->Rows->Add(w);
            }
           w[8]=L"数";w[9]=L"独";w[10]=L"総";w[11]=L"数";w[12]=L":";w[13]=s1.ToString();
           dataGridView1->Rows->Add(w);
         }
  private: System::Void backgroundWorker2_DoWork(System::Object^ sender, System::ComponentModel::DoWorkEventArgs^ e) {
          s2=0;
          f2(0);
        }
  private: System::Void backgroundWorker2_RunWorkerCompleted(System::Object^ sender, System::ComponentModel::RunWorkerCompletedEventArgs^ e) {
          array<String^>^ w=gcnew array<String^>(14);
          char i,j,k,l;
          for(i=0;i<25;i++){
            for(j=0;j<n;j++){
              if(j%3==0){
                  for(k=0;k<13;k++)w[k]=L"*";
                  dataGridView1->Rows->Add(w);
                }
                l=0;
                for(k=0;k<n;k++){
                  if(k%3==0){
                  w[k+l]=L"*";
                  l++;
                }
                w[k+l]=(as2[i][j][k]).ToString();
              }
              w[k+l]=L"*";
              dataGridView1->Rows->Add(w);
            }
            for(k=0;k<13;k++)w[k]=L"*";
            dataGridView1->Rows->Add(w);
            for(j=0;j<13;j++)w[j]=L"";
            dataGridView1->Rows->Add(w);
          }
         w[8]=L"数";w[9]=L"独";w[10]=L"総";w[11]=L"数";w[12]=L":";w[13]=s2.ToString();
         dataGridView1->Rows->Add(w);
       }
  private: System::Void backgroundWorker3_DoWork(System::Object^ sender, System::ComponentModel::DoWorkEventArgs^ e) {
          s3=0;
          f3(0);
       }
  private: System::Void backgroundWorker3_RunWorkerCompleted(System::Object^ sender, System::ComponentModel::RunWorkerCompletedEventArgs^ e) {
          array<String^>^ w=gcnew array<String^>(14);
          char i,j,k,l;
          for(i=0;i<25;i++){
            for(j=0;j<n;j++){
              if(j%3==0){
                for(k=0;k<13;k++)w[k]=L"*";
                dataGridView1->Rows->Add(w);
              }
              l=0;
              for(k=0;k<n;k++){
                if(k%3==0){
                  w[k+l]=L"*";
                  l++;
                }
                w[k+l]=(as3[i][j][k]).ToString();
              }
              w[k+l]=L"*";
              dataGridView1->Rows->Add(w);
            }
            for(k=0;k<13;k++)w[k]=L"*";
            dataGridView1->Rows->Add(w);
            for(j=0;j<13;j++)w[j]=L"";
            dataGridView1->Rows->Add(w);
          }
          w[8]=L"数";w[9]=L"独";w[10]=L"総";w[11]=L"数";w[12]=L":";w[13]=s3.ToString();
          dataGridView1->Rows->Add(w);
        }
  private: System::Void backgroundWorker4_DoWork(System::Object^ sender, System::ComponentModel::DoWorkEventArgs^ e) {
          s4=0;
          f4(0);
        }
        private: System::Void backgroundWorker4_RunWorkerCompleted(System::Object^ sender, System::ComponentModel::RunWorkerCompletedEventArgs^ e) {
          array<String^>^ w=gcnew array<String^>(14);
          char i,j,k,l;
          for(i=0;i<25;i++){
            for(j=0;j<n;j++){
              if(j%3==0){
                for(k=0;k<13;k++)w[k]=L"*";
                dataGridView1->Rows->Add(w);
              }
              l=0;
              for(k=0;k<n;k++){
                if(k%3==0){
                  w[k+l]=L"*";
                  l++;
                }
                w[k+l]=(as4[i][j][k]).ToString();
              }
              w[k+l]=L"*";
              dataGridView1->Rows->Add(w);
            }
            for(k=0;k<13;k++)w[k]=L"*";
            dataGridView1->Rows->Add(w);
            for(j=0;j<13;j++)w[j]=L"";
            dataGridView1->Rows->Add(w);
          }
          w[8]=L"数";w[9]=L"独";w[10]=L"総";w[11]=L"数";w[12]=L":";w[13]=s4.ToString();
          dataGridView1->Rows->Add(w);
        }
  private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {

          n=9;
          g(n);
          backgroundWorker1->RunWorkerAsync();
          backgroundWorker2->RunWorkerAsync();
          backgroundWorker3->RunWorkerAsync();
          backgroundWorker4->RunWorkerAsync();
        }

        static void g(char n){
          char i,j;
          for(i=0;i<n*n;i++){
            x[i]=i%n;
            y[i]=i/n;
          }
        }
        static void f1(char g){
          if(s1==25)return;
          int i,j,k,h,kk,kkk,xs,ys;

          rand();
          kk=rand()%n;

          for(i=0;i<n;i++){
            kkk=(kk+i)%n+1;
            a1[y[g]][x[g]]=kkk;
            //a1[y[g]][x[g]]=i+1;
            h=1;
            if(x[g]>0){
              for(j=0;j<x[g];j++){
                if(a1[y[g]][x[g]]==a1[y[g]][j]){
                  h=0;
                  break;
                }
              }
            }
            if(h==1){
              if(y[g]>0){
                for(j=0;j<y[g];j++){
                  if(a1[y[g]][x[g]]==a1[j][x[g]]){
                     h=0;
                     break;
                  }
                }
              }
            }

            if(h==1){
              xs=x[g]/3;
              ys=y[g]/3;
              for(j=0;j<=y[g]-3*ys;j++){
                for(k=0;k<3;k++){
                  if(j==y[g])if(k==x[g])break;
                  if((y[g]!=3*ys+j) && (x[g]!=3*xs+k)){
                    if(a1[y[g]][x[g]]==a1[3*ys+j][3*xs+k]){
                      h=0;
                      break;
                    }
                  }
                }
                if(h==0)break;
             }
           }

           if(h==1){
             if(g<n*n-1){
               f1(g+1);
             }
             else{
               for(j=0;j<n;j++){
                 for(k=0;k<n;k++){
                    as1[s1][j][k]=a1[j][k];
                 }
               }
               s1++;
               if(s1==25)return;

             }
           }
         }
       }

       static void f2(char g){
         if(s2==25)return;
         int i,j,k,h,kk,kkk,xs,ys;


         rand();
         rand();
         kk=rand()%n;

         for(i=0;i<n;i++){
           kkk=(kk+i)%n+1;
           a2[y[g]][x[g]]=kkk;
           //a2[y[g]][x[g]]=i+1;
           h=1;
           if(x[g]>0){
           for(j=0;j<x[g];j++){
             if(a2[y[g]][x[g]]==a2[y[g]][j]){
               h=0;
               break;
             }
           }
         }
         if(h==1){
           if(y[g]>0){
             for(j=0;j<y[g];j++){
               if(a2[y[g]][x[g]]==a2[j][x[g]]){
                 h=0;
                 break;
               }
             }
           }
         }

         if(h==1){
           xs=x[g]/3;
           ys=y[g]/3;
           for(j=0;j<=y[g]-3*ys;j++){
             for(k=0;k<3;k++){
               if(j==y[g])if(k==x[g])break;
               if((y[g]!=3*ys+j) && (x[g]!=3*xs+k)){
                  if(a2[y[g]][x[g]]==a2[3*ys+j][3*xs+k]){
                    h=0;
                    break;
                  }
               }
             }
             if(h==0)break;
           }
         }

         if(h==1){
           if(g<n*n-1){
             f2(g+1);
           }
           else{
             for(j=0;j<n;j++){
               for(k=0;k<n;k++){
                  as2[s2][j][k]=a2[j][k];
               }
             }
             s2++;
             if(s2==25)return;

           }
         }
       }
     }
     static void f3(char g){
       if(s3==25)return;
       int i,j,k,h,kk,kkk,xs,ys;
       rand();
       rand();
       kk=rand()%n;

       for(i=0;i<n;i++){
         kkk=(kk+i)%n+1;
         a3[y[g]][x[g]]=kkk;
         //a3[y[g]][x[g]]=i+1;
         h=1;
         if(x[g]>0){
           for(j=0;j<x[g];j++){
             if(a3[y[g]][x[g]]==a3[y[g]][j]){
               h=0;
               break;
             }
           }
         }
         if(h==1){
           if(y[g]>0){
             for(j=0;j<y[g];j++){
               if(a3[y[g]][x[g]]==a3[j][x[g]]){
                 h=0;
                 break;
               }
             }
           }
         }

         if(h==1){
           xs=x[g]/3;
           ys=y[g]/3;
           for(j=0;j<=y[g]-3*ys;j++){
             for(k=0;k<3;k++){
               if(j==y[g])if(k==x[g])break;
                 if((y[g]!=3*ys+j) && (x[g]!=3*xs+k)){
                   if(a3[y[g]][x[g]]==a3[3*ys+j][3*xs+k]){
                     h=0;
                     break;
                   }
                 }
               }
               if(h==0)break;
             }
           }

           if(h==1){
             if(g<n*n-1){
               f3(g+1);
             }
             else{
               for(j=0;j<n;j++){
                 for(k=0;k<n;k++){
                   as3[s3][j][k]=a3[j][k];
                 }
               }
               s3++;
               if(s3==25)return;

             }
           }
         }
       }
       static void f4(char g){
         if(s4==25)return;
         int i,j,k,h,kk,kkk,xs,ys;

         rand();
         rand();
         rand();
         rand();
         kk=rand()%n;

         for(i=0;i<n;i++){
            kkk=(kk+i)%n+1;
            a4[y[g]][x[g]]=kkk;
            //a4[y[g]][x[g]]=i+1;
            h=1;
            if(x[g]>0){
             for(j=0;j<x[g];j++){
               if(a4[y[g]][x[g]]==a4[y[g]][j]){
                 h=0;
                 break;
               }
             }
           }
           if(h==1){
             if(y[g]>0){
               for(j=0;j<y[g];j++){
                 if(a4[y[g]][x[g]]==a4[j][x[g]]){
                   h=0;
                   break;
                 }
               }
             }
           }

           if(h==1){
             xs=x[g]/3;
             ys=y[g]/3;
             for(j=0;j<=y[g]-3*ys;j++){
               for(k=0;k<3;k++){
                 if(j==y[g])if(k==x[g])break;
                 if((y[g]!=3*ys+j) && (x[g]!=3*xs+k)){
                    if(a4[y[g]][x[g]]==a4[3*ys+j][3*xs+k]){
                      h=0;
                      break;
                    }
                 }
               }
               if(h==0)break;
             }
           }

           if(h==1){
             if(g<n*n-1){
               f4(g+1);
             }
             else{
             for(j=0;j<n;j++){
               for(k=0;k<n;k++){
                 as4[s4][j][k]=a4[j][k];
               }
             }
             s4++;
             if(s4==25)return;

           }
         }
       }
     }

  };
}


ダウンロード用ファイルForm16.h

if(s4==25)return;
などを
if(s4==2000)return;と変更して実行すると、

とCPU使用率100%が実現できていることがわかります。



さて、皆さん問題です。
今回マルチスレッドによって高速化を図りましたが、

  private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {

          n=9;
          g(n);
          backgroundWorker1->RunWorkerAsync();
          backgroundWorker2->RunWorkerAsync();
          backgroundWorker3->RunWorkerAsync();
          backgroundWorker4->RunWorkerAsync();
        }
を見ていただければわかるように、時間計測をしていません。
そこで、
  private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
          DateTime^ hj=DateTime::Now;
          n=9;
          g(n);
          backgroundWorker1->RunWorkerAsync();
          backgroundWorker2->RunWorkerAsync();
          backgroundWorker3->RunWorkerAsync();
          backgroundWorker4->RunWorkerAsync();
          array<String^>^ w=gcnew array<String^>(14);
          DateTime^ ow=DateTime::Now;
          TimeSpan sa=ow->Subtract(*hj);
          w[16]=L"時";w[17]=L"間";w[18]=L"計";w[19]=L"則";w[20]=L":";w[21]=(sa.TotalSeconds).ToString();
          dataGridView1->Rows->Add(w);

       
 }
と変更すれば、時間計測はできるでしょうか。


第24講第5話へ 第24講第7話へ

戻る

VC++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座