第21講 末項確定法
第6話 末確定法の改良の試み

講義はこの後この末講確定法の改良に取り組むはずでした。
その改良というのは、例えば、

0 1 2 3 4 5 6 7 8 9
0 20 21 22 23 24 25 26 27 10
1 28 36 37 38 39 40 41 11 42
2 29 43 50 51 52 53 12 54 55
3 30 44 56 62 63 13 64 65 66
4 31 45 57 67 14 72 73 74 75
5 32 46 58 68 15 80 81 82 83
6 33 47 59 16 76 84 6 88 89 90
7 34 48 17 69 77 85 91 7 94 95
8 35 18 60 70 78 86 92 96 8 98
9 19 49 61 71 79 87 93 97 99 9

と数字が入ってきたとき、この後最大数9を残りに入れたとしても、

0 1 2 3 4 5 6 7 8 9
0 20 21 22 23 24 25 26 27 10
1 28 36 37 38 39 40 41 11 42
2 29 43 50 51 52 53 12 54 55
3 30 44 56 62 63 13 64 65 66
4 31 45 57 67 14 72 73 74 75
5 32 46 58 68 15 80 81 82 83
6 33 47 59 16 76 84 88 89 90
7 34 48 17 69 77 85 91 94 95
8 35 18 60 70 78 86 92 96 98
9 19 49 61 71 79 87 93 97 99


0+1+1+2+2+0+9+9+9+9=42にしかなりません。
つまり、10次魔方陣の場合、対角線の合計などは
0+1+2+3+4+5+6+7+8+9=45
でなければなりませんが、それに届かないのです。ですから

0 1 2 3 4 5 6 7 8 9
0 20 21 22 23 24 25 26 27 10
1 28 36 37 38 39 40 41 11 42
2 29 43 50 51 52 53 12 54 55
3 30 44 56 62 63 13 64 65 66
4 31 45 57 67 14 72 73 74 75
5 32 46 58 68 15 80 81 82 83
6 33 47 59 16 76 84 6 88 89 90
7 34 48 17 69 77 85 91 7 94 95
8 35 18 60 70 78 86 92 96 8 98
9 19 49 61 71 79 87 93 97 99 9

の時点で上の世界に行って探索するは意味がないので、

0 1 2 3 4 5 6 7 8 9
0 20 21 22 23 24 25 26 27 10
1 28 36 37 38 39 40 41 11 42
2 29 43 50 51 52 53 12 54 55
3 30 44 56 62 63 13 64 65 66
4 31 45 57 67 14 72 73 74 75
5 32 46 58 68 15 80 81 82 83
6 33 47 59 16 76 84 6 88 89 90
7 34 48 17 69 77 85 91 7 94 95
8 35 18 60 70 78 86 92 96 8 98
9 19 49 61 71 79 87 93 97 99 9

上の世界には行かないで、

の数字が3になるまでループしてからはじめて、
f2(g+1)とすべきなのです。

0 1 2 3 4 5 6 7 8 9
0 20 21 22 23 24 25 26 27 10
1 28 36 37 38 39 40 41 11 42
2 29 43 50 51 52 53 12 54 55
3 30 44 56 62 63 13 64 65 66
4 31 45 57 67 14 72 73 74 75
5 32 46 58 68 15 80 81 82 83
6 33 47 59 16 76 84 6 88 89 90
7 34 48 17 69 77 85 91 7 94 95
8 35 18 60 70 78 86 92 96 8 98
9 19 49 61 71 79 87 93 97 99 9

これならば、以後すべて9を入れていけば、
0+1+1+2+2+3+9+9+9+9=45
で合計を45にすることができます。

対角線や列など半分以上数字が入ってきた段階で、
常にその可能性があるので、

if(g>m && g<n-1){
  wa=0;
  for(j=0;j<g-1;j++){
   wa+=a1[j][j];
  }
  sa=n*(n-1)/2-wa;
  if(sa<0 || sa>(n-1)*(n-g))return;
}
などを入れて、改良するつもりだったのです。
ところが、作成速度の向上はほとんどありませんでした。

これはおそらく数字をランダムに入れているので、

0 1 2 3 4 5 6 7 8 9
0 20 21 22 23 24 25 26 27 10
1 28 36 37 38 39 40 41 11 42
2 29 43 50 51 52 53 12 54 55
3 30 44 56 62 63 13 64 65 66
4 31 45 57 67 14 72 73 74 75
5 32 46 58 68 15 80 81 82 83
6 33 47 59 16 76 84 6 88 89 90
7 34 48 17 69 77 85 91 7 94 95
8 35 18 60 70 78 86 92 96 8 98
9 19 49 61 71 79 87 93 97 99 9

のように片寄ってはいるのは、確率的に少ないので、
かえって、
if(g>m && g<n-1){
  wa=0;
  for(j=0;j<g-1;j++){
   wa+=a1[j][j];
  }
  sa=n*(n-1)/2-wa;
  if(sa<0 || sa>(n-1)*(n-g))return;
}
などと探索する時間が無駄だということかと思われます。

私は、改良の試みに失敗しましたが、興味がある方は是非挑戦して下さい。

というわけで、この講は閉じたいと思います。
第22講では、素数探索を題材にしていよいよマルチスレッド対応プログラミングに挑みます。



第21講第5話へ 第22講第1話へ



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