第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);
}
と変更すれば、時間計測はできるでしょうか。
VC++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual
Basic入門基礎講座