第11講 Subプロシージャの再帰的使用の学習

第2話 Subプロシージャの再帰的使用とは? 

1 2 3 4 5 6 7 8 9
4 5 6 7 8 9 1 2 3
7 8 9 1 2 3 4 5 6
2 1 4 3 6 5 8 9 7
3 6 5 8 9 7 2 1 4
8 9 7 2 1 4 3 6 5
5 3 1 6 4 2 9 7 8
6 4 2 9 7 8 5 3 1
9 7 8 5 3 1 6 4 2

数独(ナンバープレイス)の場合、完全に同一条件=同一構造のセル(細胞)が81個並んでいます。
一つ一つのセルを、ひとつのプロシージャが分担するとすると、81個のプロシージャを用意しなければなりません。
でもこれは無駄です。
それぞれのセルで処理することは、
@ 列の重複チェック
A 行の重複チェック
B ブロックの重複チェック
のすべてがクリアできたら、1以上9以下の整数を入れることです。
処理は同一なのです。
ですから、81個のプロシージャを用意することは全くの無駄です。
処理内容が同一なのですから、1個のプロシージャを用意すればよいのです。
では、81回もプロシージャを呼び出さなければならないでしょうか。

実は、実行プログラムであるPrivate Sub CommandButton1_Clickからは1回の呼び出しで済むように出来ます。
結果的には確かに81回呼び出すのですが、Private Sub CommandButton1_Clickからは1回だけ呼び出せば、
自動的に81回プロシージャを呼び出せるように出来るのです。
それが再帰的使用です。
再帰的使用のことを自己再帰ともいいます。
自己に再び変えるとはどういうことでしょうか。

それは、自己を自己から呼び出せばよいのです。
自分が自分を呼び出したとき、帰る先は自分です。

自己再帰とは、ロシアの入れ子式人形を思い浮かべていただければよいと思います。
Private Sub CommandButton1_Clickから、最初に一番大きい人形=一番外側の人形を呼び出します。
人形は、さらに人形を呼び出します。
一番大きい人形=一番外側の人形が、2番目に大きい人形=外から2番目の人形を呼び出します。
外から2番目の人形は、外から3番目の人形を呼び出します。
以下繰り返し、
外から6番目の人形が、外から7番目の人形を呼び出します。
そして、一番小さい人形にたどり着いたとき(数独でいえば81番目のセルにたどり着いたとき)、自分探しの旅が終わります。
自分のより深い起源=本質を求める旅が終わりを告げるのです。
自分の一番深い本質=起源が、入れ子式の一番小さい人形であることがわかったら(数独の場合は、数独が完成したら)、
旅路は、逆順をたどることになります。
一番内側の人形から、内側から2番目へと帰ります。
そして、内側から2番目から、3番目への還帰となります。
同様に次々に外側に帰り、一番外側に帰り着きます。
最後に、一番外側からPrivate Sub CommandButton1_Clickへ帰り着いて自分探しの旅は終わりとなります。

どんどん自分のより深い本質を求めて、深く遡及していって本質を見いだしたらもとの自分に返ることによって、
自分が何であるかを明らかにします。

確かに、自分を自分が呼び出しますが、同じ自分でも実は、外側に人形が内側の人形を呼び出すように、
次元の違う自分です。
ここを理解するかどうかが、自己再帰を理解するときのキーとなります。
自分が自分を呼び出しているが、呼び出す自分と呼び出される自分は次元の違う自分です。
さらに、呼び出された自分から呼び出した自分に帰りますが、
呼び出された自分と呼び出した自分も次元が違いますので、次元の異なる自分に帰るのです。

入れ子式人形で比喩的に説明してきましたが、
もう1回数独で説明し直しましょう。
Private Sub CommandButton1_Clickは、1番目のセルを呼び出します。
1番目のセルは、2番目のセルを呼び出します。
呼び出す自分と呼び出される自分は、次元が違うと申し上げましたが、
1番目のセルと2番目のセルは、まったく同一の構造をもっていますが、異なるセルです。
再帰的使用=自己再帰では、今自分がどこの世界(セル)にいるのかを明確にしなければなりません。
2番目のセルは、3番目のセルを、3番目のセルは、4番目のセルを、・・・・、と呼びだしていって、
最終的には、80番目のセルが81番目のセルを呼び出します。
これで1個目の数独は完成します。
1個目が完成したら、2個めの数独を探すために、80番目のセルに戻り、81番目を呼び出してうまくいくかを確認します。
だめなら、何回も逆遡及をしていって、また遡及します。
逆遡及と遡及を何回も何回も繰り返すことによって、
プログラムはすべての解答を見つけようとします。

今回は、抽象的な説明に終始しました。
後に数独解答自動作成プログラムに挑戦しますが、そのときは是非ここに戻って熟読して下さい。

次話からいよいよ順列の具体的なプログラムに着手します。
次のシートとコード作ってください。
シート
Dim a(15) As Byte
Dim cn As Long
Dim n As Byte
Private Sub CommandButton1_Click()

  n = Cells(2, 10)
  cn = 0
  f (0)

  Cells(3, 13) = cn

End Sub

Sub f(g As Integer)
   ・
   ・
   ・
   〜f(g+1)〜
   ・
   ・
   ・
End Sub

Private Sub CommandButton2_Click()

  Rows("5:20000").Select
  Selection.ClearContents
  Range("J2,M3").Select
  Selection.ClearContents
  Cells(1, 1).Select
End Sub
J2に値を入力すると、
実行画面例
となるようにSubプロシージャfを考えてください。
再帰的使用なのでf(g+1)は不可避です。f(g)がf(g+1)を呼び出しています。
ここでgはセル番号です。

つまり、上の表の0,1,2に相当するものです。gは、世界(セル)の次元番号です。



第1話へ 第3話へ

004
  


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

数学研究室に戻る