SE_BOKUのまとめノート的ブログ

SE_BOKUが知ってること・勉強したこと・考えたことetc

再帰処理を使ってハノイの塔の解を求める/Python文法

f:id:arakan_no_boku:20190223210405j:plain

目次

再帰処理を使ってハノイの塔の解を求める

Pythonで再起処理をやってみます。

Python文法ってサブタイトルつけてますが・・文法的に再帰構文があるわけではなくて「再帰的な処理」のパターンも広義的に考えれば含むかな・・という程度のことです。

再帰処理とは

再帰再帰的)は「(数学的には)定義の中に定義されるものが含まれていること」で、Pythonプログラムに置き換えてみれば「関数(自分)の中で自分を呼び出し、結果を受け取る」ような感じです。

用語的には。

という呼び方をします。

再起処理は言葉だけだと、とてもイメージしづらいので、サンプル的に「ハノイの塔」の解を求めるプログラムをPythonで書きながら整理します。

ハノイの塔とは

有名なパズルで、下の図のように、3本の柱があって、一番左端(A)に何枚か(例では3枚)の円盤がささっているところからスタートします。

f:id:arakan_no_boku:20170303232100j:plain

円盤を1枚ずつ動かして、真ん中の柱(B)に移すパズルです。

円盤は図のように全部大きさが違い、下の段ほど大きい円盤になっているのですが、動かす途中であっても、小さい円盤の上に、大きい円盤をのせてはいけません。

このルールを守って一枚ずつ動か菓子、以下のようになればOKです。

f:id:arakan_no_boku:20170304131001j:plain

円盤の数が3枚なら「3ハノイ」、4枚なら「4ハノイ」のように、円盤の数+ハノイで呼ぶのが一般的で、当たり前ですが、円盤の数が少ないほど簡単です。

ハノイの塔を解くアルゴリズム

このサイトによると、「2のN乗 -1(Nは円盤の数)」回で解けるのが最短手順とのことです。

mathtrain.jp

つまり、円盤3枚なら手順は7回(2の3乗-1)で解けるということです。

ハノイの塔には、問題を解くアルゴリズムが存在し、上記のサイトの記事よれば。

f:id:arakan_no_boku:20170304002645j:plain

となっています。

A(n)に対して内部でA(n-1)を用いるということは、A()という関数を再帰的に呼び出しているということなので、まさに「再帰処理」です。

pythonでの実装

早速、pythonでやってみました。

ほぼ、上記のアルゴリズムをソースにおとしただけです。

def hanoi(n, a, b, c):
    hanoi_imp(n, a, b, c)


def hanoi_imp(n, a, b, c):
    if n <= 0:
        pass
    else:
        hanoi_imp(n - 1, a, c, b)
        print(a + u" → " + b)
        hanoi_imp(n - 1, c, b, a)


hanoi(3, "A", "B", "C") 

 

引数のnに円盤の枚数をわたし、a,b,c には、表示用にA,B,Cの文字を渡します。 

再帰呼び出しをするところで、引数で渡されてa,b,cの位置を入れ替えないといけない所が、ちょっと工夫が必要でしたが、ほぼ、まんまです。

この中で「pass」と書いているところが「何もしない」処理です。

あと、hanoi_imp()の中で、自分自身(hanoi_imp)を呼び出してます。

これが再帰処理です。

このテクニックを使うと「複雑に行われる処理を簡単に書くことができる」メリットがあるのですけど、慣れないと、結果がまったくイメージできない・・という悩ましいところがあります。

プログラムの実行結果

これを、math_hanoi.py という名前で保存して実行してみます。

python math_hanoi.py

結果は。

A→B
A→C
B→C
A→B
C→A
C→B
A→B

とりあえず、5ハノイまではプログラムの出力を見ながら、実際にやって回答を検証しましたが、OKでした。 

6ハノイ以上は試してませんが、大丈夫と思います。

ではでは。