C言語で遺伝的アルゴリズムの順序交叉を実装していますが、処理が遅いです。解決策を教えてください。

このQ&Aのポイント
  • C言語を使って遺伝的アルゴリズムの順序交叉(TSP)を実装していますが、処理が非常に遅いです。
  • 循環交叉を取り入れたプログラムは5000ループでも1秒弱で処理されますが、順序交叉では20秒近くかかってしまいます。
  • 無駄なループが多いように思えますが、改善策が思いつきません。ヒントを教えてください。
回答を見る
  • ベストアンサー

交叉について

c言語を使い始めて、TSPについて勉強中で、遺伝的アルゴリズムの交叉(順序交叉)について以下のプログラムを作ってみたのですが、凄く遅いです。答えはきちんと出るのですが、循環交叉を取り入れたプログラムは5000ループでも1秒弱で出るのに対して20秒近くかかってしまいます。ループに無駄が多そうなのですが思いつきません。ヒントでも宜しいのでご教授下さい。 順序交叉とは、例えば x[i] = 3,4,5,2,1とy[i] = 4,3,5,1,2(i = 0~)という数字が与えられたときtargetを2とすると x[i] = 3,4, y[i] = 4,3まではそのまま受け継ぎ、3以降は相手方の数字を左から順番に使われていないものを取り入れていくものです。この場合だと、x[i] = 3,4,5,1,2 y[i] = 4,3,5,2,1となります。 #define a 5 int main(void) {    int x[a] = {3, 4, 5, 2, 1}, y[a] = {4, 3, 5, 1, 2};    int target, i, j, k, l;    int x2[a], y2[a];    srand((unsigned)time(NULL));    target = rand () % a;    for (i = 0; i < target; i++) {       x2[i] = x[i];       y2[i] = y[i];    }    for (i = target; i < a; i++) {       x2[i] = 0;       y2[i] = 0;    }    j = 0;    k = 0;    while (k != a - target) {       for (i = 0; i < target + k; i++) {          for (l = 0; l < target + k; l++) {             if (x2[l] == y[j])                j++;          }       }       if (x2[target + k] != y[j]) {          x2[target + k] = y[j];          k++;          j++;       }       else          j++;    }    yについても同様の作業です }

質問者が選んだベストアンサー

  • ベストアンサー
  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.1

パッと思いついたところだけ。 出現済みチェック(かな?)の二重ループ。jがインクリメントされなければ、次のiのループでもインクリメントされないので、ループしなくても良いかと。こんな感じ: while (k != a - target) { for (i = 0; i < target + k; i++) { int prev_j = j; // jを記憶。 for (l = 0; l < target + k; l++) { if (x2[l] == y[j]) j++; } printf( "j: %d->%d?n", prev_j, j ); //デバッグ用。 if ( prev_j == j ){break;} // jに変化無ければブレーク。 } 遺伝子が重複無く存在するような表現式なのだとしたら、以下のやり方でもいけるかも。 for (i = 0; i < target; i++) { // 交叉直前まで遺伝。 x2[i] = x[i]; } for (i = 0; i < a; i++) { // 片親を作業領域にコピー。 y2[i] = y[i]; } for ( j = 0; j < target; j++ ){ for ( i = 0; i < a; i++ ){ if ( x2[j] == y2[i] ){ y2[i] = 0; } // 既に遺伝済みのものは引き継がないよう片親側に0でマーク。 } } i = 0; for( k = target; k < a; k++ ){ // 片親から残りを遺伝。 while ( y2[i] == 0 ){ i++; } // マークされている部分をスキップ。 x2[k] = y2[i++]; } }

revolution_2005
質問者

お礼

有難う御座いました。おかげで、循環交叉と同じ位のスピードで処理出来るようになりました。大変勉強になりました。また質問するようなことがあったら宜しく御願い致します。

関連するQ&A

  • 配列のエラーに関して

    java言語を用いて,Householder変換を用いた固有値の数値計算に挑戦してみました.しかし,次のようなエラーが発生し上手くいきません.どなたかこの問題を解決するためにお力をかしていただけないでしょうか. ----------エラー内容-------------------------------------------------------------------------------- Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0 at Out.Mhouse(House.java:90) at House.main(House.java:10) ---------------------------------------------------------------------------------------------------- //Householder変換 public class House{ public static void main(String[] args){ double[][] A = new double[3][3]; int n = A.length; Out out = new Out(); for(int i = 0;i < n;i++){ for(int j = 0;j < n;j++){ if(j < n-1){ System.out.print(out.Mhouse(A)[i][j] + " "); }else if (j == n-1) System.out.println(out.Mhouse(A)[i][j]); }; }; }; }; class Out{ double[][] outpro(double[] x){ int n; n = x.length; double[][] A = new double[n][n]; for(int i = 0;i < n;i++ ){ for(int j = 0;j < n;j++){ A[i][j] = x[i] * x[j]; } } return A; }; double[][] Msca(double a,double[][] A){ int n = A.length; for(int i = 0;i < n; i++){ for(int j = 0;j < n;j++){ A[i][j] = a * A[i][j]; } } return A; }; double selfpro(double[] x){ double a = 0; int n = x.length; for(int i = 0;i < n; i++){ a = a + x[i] * x[i]; }; return a; }; double[] minus(double[] x, double[] y){ int n = x.length; double[] z = new double[n]; for(int i = 0;i < n;i++){ z[i] = x[i] - y[i]; }; return z; }; double[][] house_1(double[] x){ int n = x.length; double[][] A = new double[n][n]; for(int i=0;i < n;i++){ for(int j = 0;j < n;j++){ if(i == j){ A[i][j] = 1 - Msca(2/selfpro(x),outpro(x))[i][j]; }else{ A[i][j] = - Msca(2/selfpro(x),outpro(x))[i][j]; }; }; }; return A; }; double[][] house_2(double[] x){ double[][] z = new double[1][1]; z[1][1] = 1 - 2; return z; }; double[][] Mhouse(double[][] A){ int n = A.length; double[][] H = new double[n][n]; for(int i = 0;i < n;i++){ double[] x = new double[n-i]; double[] y = new double[n-i]; double[][][] L = new double[i][n-i][n-i]; for(int j = 0;j < n-i;j++){ x[j] = A[i][i+j]; if(j == 0){ y[j] = 1; }else{ y[j] = 0; }; x[j] = y[j] - x[j]; }; if(i < n-1){ L[i] = house_1(x); for(int k = 0;k < n-i;k++){ for(int l = 0;l < n-i;l++){ H[i+k][i+l] = L[i][k][l]; }; }; }else if(i == n-1){ L[i] = house_2(x); for(int k = 0;k < n-i;k++){ for(int l = 0;l < n-i;l++){ H[i+k][i+l] = L[i][k][l]; }; }; }; }; double[][] B = new double[n][n]; for(int i = 0;i < n;i++){ for(int j = 0;j < n;j++){ for(int k = 0;k < n;k++){ B[i][j] = H[i][k] * A[k][j]; }; }; }; return A; }; };

    • ベストアンサー
    • Java
  • 有限体GF(4)上の同次方程式で不定方程式

    連立方程式の解法ですが、手計算だとうまくいくのにプログラムにしようとするとうまくいきません。 さらに不定方程式なので解がないといわれてしまいます。誰かわかる方がいらしたらプログラムを 見て直していただきたいです。プログラムは以下の通り。 #define N 4 #define T 6 unsigned char gf[4]={0,1,2,3},fg[4]={0,1,2,3}; unsigned char gf[4]={0,1,2,3},fg[4]={0,1,2,3}; unsigned char ad[4][4]; /* 答えは 1,1,2 */ unsigned char s[3][3]={{1,3,1},{3,3,0},{1,0,3}}; /* 答えはzを不定として1と置き、x=z=1;y=0;になる筈だがならない */ //unsigned char s[][]={{2,2,2},{2,0,2},{2,2,2}} int add(int x,int y){ return ad[x][y]; } int mlt(int x, int y){ if(x==0||y==0) return 0; return ((x+y-2)%(N-1))+1; } int mltn(int n,int x){ int i,j; if(n==0) return 1; i=x; for(j=0;j<n-1;j++) i=mlt(i,x); return i; } int div(int x,int y){ if(x==0) return 0; return ((x-y+(N-1))%(N-1))+1; } void syn(){ int i,j,k,l,n; for(i=0;i<3;i++){ for(j=0;j<3;j++){ if(i==j){ if(s[i][j]==1){ for(l=0;l<3;l++){ for(k=0;k<3;k++){ s[l+1][k]=add(s[l+1][k],mlt(s[l+1][k],s[i][k])); printf("%d ",s[l][k]); } printf("\n"); } } // exit(1); if(s[i][j]!=1){ printf("%da \n",s[i][j]); n=div(1,s[i][j]); if(n==0){ printf("%d =\n",fg[s[i][j]]); exit(1); } for(k=0;k<3;k++){ if(s[0][0]==0){printf("%d?\n",s[0][0]); exit(1);} s[i][k]=mlt(n,s[i][k]); printf("%d ",s[i][k]); } printf("\n"); for(l=i;l<3;l++){ for(k=0;k<3;k++){ s[l+1][k]=add(s[l+1][k],mlt(s[l+1][k],s[i][k])); // printf("%d ",s[l][k]); } printf("\n"); } printf("\n"); for(l=0;l<3;l++){ for(k=0;k<3;k++) printf("%d ",s[l][k]); printf("\n"); } // exit(1); if(s[i][j]==0){ while(s[i][j]==0){ j++; } printf("i-j==%d\n",s[i+1][j]); if(s[i][j]!=0){ if(s[i][j]==1){ for(l=0;l<3;l++){ for(k=0;k<3;k++){ s[l+1][k]=add(s[l+1][k],mlt(s[l+1][k],s[i][k])); printf("%d ",s[l][k]); } printf("\n"); } } // exit(1); if(s[i][j]!=1){ printf("%da \n",s[i][j]); n=div(1,s[i][j]); if(n==0){ printf("%d =\n",fg[s[i][j]]); exit(1); } for(k=0;k<3;k++){ if(s[0][0]==0){printf("%d?\n",s[0][0]); exit(1);} s[i][k]=mlt(n,s[i][k]); printf("%d ",s[i][k]); } printf("\n"); for(l=i;l<3;l++){ for(k=0;k<3;k++){ s[l+1][k]=add(s[l+1][k],mlt(s[l+1][k],s[i][k])); // printf("%d ",s[l][k]); } printf("\n"); } printf("\n"); for(l=0;l<3;l++){ for(k=0;k<3;k++) printf("%d ",s[l][k]); printf("\n"); } }} // i++;j++; //exit(1); } } } } } for(i=0;i<3;i++){ for(j=0;j<3;j++) printf("%2d ",s[i][j]); printf("\n"); } } int main(){ int i,j; for(i=0;i<N;i++){ for(j=0;j<N;j++) ad[i][j]=fg[gf[i]^gf[j]]; } syn(); }

  • 行列について誰か確認してください。

    下記問題について自分なりに解答してみたのですが、イマイチあっているのか分かりません。どなたかご査収願います。 問題 『25行25列で、対角要素は全て2、その隣は-1、それ以外は全て0である行列の固有値を全てJacobi(ヤコビ)法で小数点以下6桁まで求め、その固有値と解法のプログラムを示せ。 ※収束基準は非対角要素の絶対値の最大値が10^-6未満となることとせよ。』 以下に上記問題についてのプログラムおよび固有値の計算結果を示します。 プログラミング言語=C言語 #include <math.h> #include <stdlib.h> #include <stdio.h> #define SIZE 25 int main(void) { double a[SIZE][SIZE]; int i, j, k, l; double max; double theta; double x, y; for (i = 0; i < SIZE; i++) { for (j = 0; j < SIZE; j++) { if (i == j - 1 || i == j + 1) a[i][j] = -1; else if (i == j) a[i][j] = 2; else a[i][j] = 0; } } while (1) { max = 0; for (i = 0; i < SIZE; i++) { for (j = 0; j < SIZE; j++) { if (i != j && max < fabs(a[i][j])) { max = fabs(a[i][j]); k = i; l = j; } } } if (max < 1.0e-6) break; theta = (a[k][k] != a[l][l]) ? atan2(-2 * a[k][l], a[k][k] - a[l][l]) / 2 : M_PI / 4; for (i = 0; i < SIZE; i++) { x = a[i][k]; y = a[i][l]; a[i][k] = cos(theta) * x - sin(theta) * y; a[i][l] = sin(theta) * x + cos(theta) * y; } for (j = 0; j < SIZE; j++) { x = a[k][j]; y = a[l][j]; a[k][j] = cos(theta) * x - sin(theta) * y; a[l][j] = sin(theta) * x + cos(theta) * y; } } for (i = 0; i < SIZE; i++) { printf("%lf\n", a[i][i]); } return 0; }

  • 5×5行列、固有値、固有ベクトル

    5つの値を入力し、それぞれの相対比を求めて行列にして、固有値と固有ベクトルを求めたいのですが、分からないので教えて下さい。下のプログラムは固有値を求めるものです。これは過去の質問にあったプログラムを少し変えてみたのですが、値が出てこないのでどうすればうまく出てくるのか教えて下さい。それと、固有ベクトルを求めるプログラムも教えて下さい。宜しくお願いします。 #include <math.h> #include <stdlib.h> #include <stdio.h> int main(void) { int i, j, k, l; double max,theta,x,y,a[5][5],b[5]; printf("値1: "); scanf("%d",&b[0]); printf("値2: "); scanf("%d",&b[1]); printf("値3: "); scanf("%d",&b[2]); printf("値4: "); scanf("%d",&b[3]); printf("値5: "); scanf("%d",&b[4]); printf("行列\n"); for(j=0;j<5;j++){ for(k=0;k<5;k++){ a[j][k]=b[k]/b[j]; printf("%1.3f ",a[j][k]); } printf("\n"); } while(1){ max=0; for(i=0;i<5;i++){ for(j=0;j<5;j++){ if (i!=j && max<fabs(a[i][j])){ max=fabs(a[i][j]); k=i; l=j; } } } if (max<1.0e-6) break; theta=(a[k][k]!=a[l][l])? atan2(-2*a[k][l],a[k][k]-a[l][l])/2:M_PI/4; for(i=0;i<5;i++){ x=a[i][k]; y = a[i][l]; a[i][k] = cos(theta) * x - sin(theta)*y; a[i][l] = sin(theta) * x + cos(theta)*y; } for (j=0;j<5;j++){ x=a[k][j]; y=a[l][j]; a[k][j]=cos(theta)*x-sin(theta)*y; a[l][j]=sin(theta)*x+cos(theta)*y; } } printf("固有値\n"); for (i=0;i<5;i++){ printf("%1.3f\n",a[i][i]); } return 0; }

  • LU分解を利用した逆行列のプログラム(Java)

    LU分解を利用した逆行列のプログラムが作れません… というか、作ったのですが実行するとエラーが出てしまいます(´Д`;) どこをどう直せばいいか、もしくはこのようにプログラムした方が効率がよい などのアドバイスどなたか下さい double a[][]={{2,5,4}, {2,3,-1}, {6,9,28}}; int N=a.length; double[][] s=new double[N][N]; for(int k=0; k<a[0].length-1; k++){ for(int i=k+1; i<N; i++){ s[i][k]=a[i][k]/a[k][k]; a[i][k]=s[i][k]; for(int j=k+1; j<N; j++){ a[i][j] -= s[i][k] * a[k][j]; } } } double[][] y=new double[N][N]; double[][] X=new double[N][N]; double[][] e=new double[N][N]; for(int i=0;i<N;i++){ for(int j=0;j<N;j++){ if(i==j){ e[i][j]=1; }else{ e[i][j]=0; } } } for(int i=0;i<N;i++){ y[1][i]=e[1][i]; for(int k=2;k<=N;k++){ for(int j=1;j<=N;j++){ y[k][i]=e[k][i]-s[k][j]*y[j][i]; } } X[N][i]=y[N][i]/a[N][N]; for(int k=N-1;k>=1;k--){ for(int j=k+1;j<=N;j++){ X[k][j]=(y[k][j]-s[k][j]*X[j][i])/a[k][k]; } } } for(int i=0;i<N;i++){ for(int j=0;j<N;j++){ System.out.printf(" %6.5f ", X[i][j] ); } System.out.println(""); }

  • 行列の積を関数を使って求める・・?

    2つの行列の行と列を入力し、積を計算するプログラムを関数を使って書きたいのですが、上手く行きません。どこをどのように直したらよいか教えてください!お願いします!! 以下が私が書いたプログラムです。 #include<stdio.h> #define NUMBER 10 int first(int x1,int x2,int y1,int y2,int i,int j,int k) { int a[NUMBER][NUMBER] = {0}; int b[NUMBER][NUMBER] = {0}; int c[NUMBER][NUMBER] = {0}; do{ printf("2つの行列の行と列を入力してください\n"); scanf("%d", &x1); scanf("%d", &x2); scanf("%d", &y1); scanf("%d", &y2); if(x1 != y2){ printf("行列の積は計算できません\n"); } }while(x1 != y2); printf("行列Aの要素を入力してください\n"); for(i=0; i<x1; i++){ for(j=0; j<x2; j++) scanf("%d", &a[i][j]); } printf("行列Bの要素を入力してください\n"); for(j=0; j<y1; j++){ for(k=0; k<y2; k++) scanf("%d", &b[j][k]); } } int second(int x1,int x2,int y1,int y2,int i,int j,int k) { int a[NUMBER][NUMBER] = {0}; int b[NUMBER][NUMBER] = {0}; int c[NUMBER][NUMBER] = {0}; for(i=0; i<x1; i++){ for(k=0; k<y2; k++){ for(j=0; j<x2; j++) c[i][k] = c[i][k] + a[i][j]*b[j][k]; } } for(i=0; i<x2; i++){ for(k=0; k<y2; k++) printf("%3d", c[i][k]); printf("\n"); } } int main(void) { int a[NUMBER][NUMBER] = {0}; int b[NUMBER][NUMBER] = {0}; int c[NUMBER][NUMBER] = {0}; printf("行列の積を計算します\n %d\n", first(x1,x2,y1,y2,i,j,k)); printf("行列Aと行Bの積は\n %3d",second(x1,x2,y1,y2,i,j,k)); }

  • 3次元配列のループによる比較の回数を減らす

    以下は正の整数が入った3次元配列form[30][20][8]で、中身が一致している2カ所に-1を代入してループを抜けるというプログラムの一部分なんですが、無駄なループを減らすにはどういった変更をすればいいでしょうか? form[30][20][8]は変更しない方向でお願いします。 check: for(int i=0;i<30;i++){ for(int j=0;j<20;j++){ for(int k=0;k<8;k++){ for(int l=0;l<30;l++){ for(int m=0;m<20;m++){ for(int n=0;n<8;n++){ if(form[i][j][k]==form[l][m][n]&&!(i==l&&j==m&&k==n)form[i][j][k]!=-1) count++; form[i][j][k]=-1; form[l][m][n]=-1; break check; } } } } } } }

    • ベストアンサー
    • Java
  • -1.#IND00と出てしまうのですが・・・

    vc++(2010)でガウスの消去法を使って連立方程式を解く、というプログラムを組みました。 正直中身自体をきちんと理解していないので、 組みながら理解しようと思って組んだのですが、 結果に-1.#IND00と出てしまいました。 これは何なのでしょうか? 下記がそのプログラムです。 #include<stdio.h> #include<math.h> #define N 3 int main(void){ double a[N][N+1] = {{2,3,4}, {3,-2,5}, {5,4,-7}}; double b[1][N+1] = {20,14,-8}; double x[N]; int i = 0; int j = 0; int k = 0; int l = 0; int pivot = 0; double p = 0; double q = 0; double m = 0; for(i = 0; i < N; i++){ x[i] = 0; } for(i = 0; i < N; i++){ pivot = i; for(l = i; l < N; l++){ if(fabs(a[l][i]) > m){ m = fabs(a[l][i]); pivot = l; } } if(pivot != i){ for(j = 0; j < N; j++){ b[0][j] = a[i][j]; a[i][j] = a[pivot][j]; a[pivot][j] = b[0][j]; } } } for(k = 0; k < N; k++){ a[k][j] = a[k][j] / p; a[k][k] = 1; for(j = k; j < N; j++){ a[k][j] = a[k][j] / p; } for(i = k+1; i < N; i++){ q = a[i][k]; for(j = k+1; j < N; j++){ a[i][j] = a[i][j] - q*a[k][j]; } a[i][k] = 0; } } for(i = N-1; i >= 0; i--){ x[i] = a[i][N]; for(j = N-1; j > i; j--){ x[i] = x[i] - a[i][j] * x[j]; } } // for(i = 0; i < N; i++){ // for(j = 0; j < N+1; j++){ // printf("%.1f", a[i][j]); // } // printf("\n"); // } // printf("解\n"); // for(i = 0; i < N; i++){ // printf("%f\n", x[i]); // } return 0; } 最後のコメントにしてある行は解を表す時と行列を表す時で使い分けているので、 実際はどちらかを外して使用しています。

  • 数独を解くアルゴリズム

    バックトラック法で解いているのですが、どこがおかしいのか見当もつかないので教えてください。 コンパイルエラーはありません。 表示の関数は省いてあります。 よろしくお願いします。 #include <stdio.h> #define M 3 //小さいブロックのサイズ #define N M*M //全体のサイズ #define MTX N*N //全体のマス数 int sudoku[N][N]={    {0,2,4,5,0,0,6,0,0},    {0,0,6,3,2,0,0,0,4},    {0,0,5,0,9,0,0,8,3},    {0,0,8,4,0,3,0,0,1},    {0,6,1,9,0,0,4,3,0},    {7,0,0,1,0,0,5,0,0},    {8,3,0,0,4,0,9,0,0},    {4,0,0,0,3,5,8,0,0},    {0,0,7,0,0,9,3,4,0}    }; /* 候補がOKかどうかチェック */ int OKkouho(int x, int y, int k) {    int i,j;    int p,q;    for(i=0; i < N; i++){ //その行に候補は入るか       if(sudoku[y][i] == k)          return 0;    }    for(j=0; j < N; j++){ //その列に候補は入るか       if(sudoku[j][x] == k)          return 0;    }    p = x/M*M;    q = y/M*M;    //そのブロックに候補は入るか    for(j = q; j < q+M; j++){       for(i = p; i < p+M; i++){          if(sudoku[j][i] == k)             return 0;       }    }    return 1; } void Solve(int level) {    int k;    int x,y;    if(level >= MTX){       printf("OK");       return;    }    x = level%N;    y = level/N;    if(sudoku[y][x])       Solve(level+1);    else{       for(k = 1; k <= N; k++){          if(OKkouho(x,y,k)){             sudoku[y][x] = k;             Solve(level+1);             sudoku[y][x] = 0;             }       }    } } int main(void) {    Solve(0);    return 0; }

  • 数独のJavaプログラム

    数独の解答を一発で出すプログラムを考えています。 自分が考えたプログラムは下記の通りです。 import java.util.Random; public class NumberPlace { public static void main(String[] args) { int i, j, k, l, check=0, count=0, tmp; int a[][] = new int [9][9]; Random rnd = new Random(); int ran; for ( i=0; i<9; i++ ) for ( j=0; j<9; j++) a[i][j] = 0; count = 0; for ( i=0; i<9; i++ ) { for ( j=0; j<9; j++) { ran = rnd.nextInt(9); tmp = ran + 1; check = 0; for ( k=0; k<j; k++ ) if ( a[i][k] == tmp ) check = 1; for ( k=0; k<i; k++ ) if ( a[k][j] == tmp ) check = 1; for ( k=(i/3)*3; k<(i/3)*3+3; k++ ) for ( l=(j/3)*3; l<(j/3)*3+3; l++ ) if ( a[k][l] == tmp ) check = 1; if ( check == 0 ) a[i][j] = tmp; if ( check == 1 ) j--; if ( count > 50000 ) break; count++; } count = 0; } for ( i=0; i<9; i++) { for ( j=0; j<9; j++ ) { if ( a[i][j] < 10 ) { System.out.print(" "); } System.out.print(a[i][j]); } System.out.print("\n"); } } } これを実行すると、正しい数独の解が出来るまでに実行を20~30回。多い時は200回前後実行しないと出来ません。 実行結果(0は数独のルール上数字が入らない所) 9 3 6 5 4 1 7 8 2 1 7 4 2 9 6 5 3 0 5 2 8 7 3 0 0 0 0 2 1 5 3 7 8 4 6 9 8 6 3 4 1 9 2 7 5 4 9 7 6 5 2 1 0 0 7 5 1 8 6 4 9 2 3 3 8 2 9 0 0 0 0 0 6 4 9 1 2 5 8 0 0 これを一発で0がない状態にしたいのです。 因みにC言語だと下記のプログラムで一発で出るのですが。(前回質問したプログラム) int main(void) { int i,j,k,l,chk=0,num=0,tmp,count=0; int a[9][9];  srand((unsigned) time(NULL)); start: count=0; for(i = 0; i < 9; i++) for(j = 0; j < 9; j++) a[i][j]=0; for(tmp=1;tmp<10;tmp++){ num=0; while(num<9){ i = rand() % 9; j = rand() % 9; chk=0; for(k=0;k<9;k++) if(a[i][k]==tmp)chk=1; for(k=0;k<9;k++) if(a[k][j]==tmp)chk=1; for(k=(i/3)*3;k<(i/3)*3+3;k++){ for(l=(j/3)*3;l<(j/3)*3+3;l++){ if(a[k][l]==tmp)chk=1; } } if((chk==0)&&(a[i][j]==0)){ a[i][j]=tmp; num++; } if(count%100==99){ count++; for(i = 0; i < 9; i++) for(j = 0; j < 9; j++) if(a[i][j]==tmp)a[i][j]=0; num=0; } if(count>10000) goto start; count++; } } for(i = 0; i < 9; i++){ for(j = 0; j < 9; j++){ printf("%d ",a[i][j]); } printf("\n"); } return 0; } このプログラムを実行すると一発で解答が出ます。 上のJavaプログラムを下のプログラムのようにするにはどうしたら良いでしょうか。

    • ベストアンサー
    • Java