再帰呼び出し / Python 07

A10e41b0a61d59f2258d7f6172c33479?s=47 kaityo256
November 12, 2019

再帰呼び出し / Python 07

プログラミング基礎同演習07

A10e41b0a61d59f2258d7f6172c33479?s=128

kaityo256

November 12, 2019
Tweet

Transcript

  1. 1 再帰呼び出し プログラミング基礎同演習 慶應義塾大学理工学部物理情報工学科 渡辺 2019/11/12 #プロ同演習

  2. 2 人口地図を作るプログラム nx, ny, nn = [], [], [] for

    x, y, n in data: nx.append(x) nx.append(y) nn.append(n ** 0.5 * 0.3) plt.figure(figsize=(15, 15), dpi=50) plt.scatter(nx, ny, c=nn, s=nn, cmap=cm.seismic) -> ValueError: x and y must be the same size エラーが起きた場所 エラーメッセージ (プロットする時はxとyは同じサイズでなければならない) 実際に問題のあった場所
  3. 3 変数の中身を見てみる 新しくセルを作り、nxを評価してみる 次にnyを評価してみると・・・ あれ?空リストになっている nyへの数値のappendがされていない? nx, ny, nn =

    [], [], [] for x, y, n in data: nx.append(x) nx.append(y) なんか大丈夫そう nyに値を入れているはずの場所を見てみる あっ →
  4. 4 エラーが起きる場所と バグを入れた場所は異なる デバッグには変数の評価が有効 (print文デバッグ)

  5. 5 観測事実:AとBが強い相関を持っている 可能性1:AがBの原因である 可能性2:BがAの原因である 可能性3:共通の要因Cを持つ 可能性4:全くの偶然である A B A B

    A B C A B
  6. 6 • 犯罪者の98%はパンを食べている • パンを日常的に食べて育った子供の約半数は、テストが 平均点以下である • 暴力的犯罪の90%は、パンを食べてから24時間以内に起 きている •

    被験者に最初はパンと水を与え、後に水だけを与える実 験をすると、2日もしないうちにパンを異常にほしがる • 新生児にパンを与えると、のどをつまらせて苦しがる • 18世紀、どの家も各自でパンを焼いていた頃、平均寿命 は50歳だった • パンを食べるアメリカ人のほとんどは、重要な科学的事 実と無意味な統計の区別がつかない ※ 同様なジョークとして「DHMO」も有名 "Bread is dangerous"で検索すると多数ヒット
  7. 7 年収と身につけている時計の値段には強い相関がある 高い年収を望むならまず高い時計を購入すべき? 朝食をとる家庭に育った子は成績が良い傾向にある 子供の成績を上げたければ朝食を作るべき?

  8. 8 アイスの売上げが多い年はプールの溺死事故が多い アイスの売上げアップ →事故も増える プールで遊ぶ人が増える 猛暑

  9. 9 http://www.tylervigen.com/spurious-correlations ニコラス・ケイジが映画に出る回数が多いとプールで溺死する人が増える 相関係数 0.67

  10. 10 http://www.tylervigen.com/spurious-correlations ミス・アメリカの年齢と暖房器具による死亡事故の件数 相関係数 0.87 ※年齢や回数など、とり得る値の範囲が少ない場合は疑似相関が出やすい

  11. 11 可能性1:AがBの原因である 可能性2:BがAの原因である 可能性3:共通の要因Cを持つ 可能性4:全くの偶然である 答:このデータだけではわからない 問:カラーテレビの普及率(A)と寿命の長さ(B)に 強い相関(0.95)が観測された。原因は以下のどれか? 共通因子「経済的余裕」が疑われるが、それを調べるためには、同等 な経済状態でテレビが無い地域の寿命を調べる必要がある

  12. 12 再帰呼び出し

  13. 13 再帰的定義:定義の記述に自分自身があらわれるもの フォルダ:その中にフォルダとファイルを含むもの A B B X Y Z

  14. 14 ある関数が、自分自身を呼び出すこと def func(): func() 上記のプログラムは、funcがfuncを呼び、呼び出さ れたfuncがまたfuncを呼び…と、実行が終わらない 再帰呼び出しには、必ず終端条件が必要

  15. 15 自然数の階乗を返す関数fact(n)が作りたい def fact(n): a = 1 for i in

    range(1, n+1): a *= i return a 以下のようにループを回してしまうのが簡単だが、再帰で考えてみる
  16. 16 1. 再帰とは、自分自身を呼び出す関数である 2. 関数の最初に「終端条件」を記述する 3. 「解きたい問題より小さな問題」に分解して 自分自身を呼び出す ※必ずしも上記に当てはまらない再帰もあるが、まずはこれが基本だと覚えること

  17. 17 「今解きたい問題よりも小さな問題の答えが全 てわかっている場合、解きたい問題の答えはど う記述できるだろうか?」 nの階乗fact(n)について、fact(n-1)の答えがわかっているなら、 fact(n) = n * fact(n-1)

    階乗の場合: fact(n) fact(n-1)
  18. 18 fact(n) = n * fact(n-1) fact(n-1) = (n-1) *

    fact(n-2) ... fact(2) = 2 * fact(1) 「分解」を繰り返すと、いつか「これ以上分解できない状態」に到達する 終端条件 ※ 0!=1としてfact(0)まで考えても結果は同じ ここでおしまい
  19. 19 def fact(n): if n == 1: return 1 return

    n * fact(n-1) 終端条件は(原則として)関数の最初に記述する 終端条件
  20. 20 階乗を計算する関数 def fact(n): if n == 1: return 1

    return n * fact(n-1) 1. 定義中に自分自身を呼び出している 2. 関数の最初に終端条件がある 3. 「より小さな問題」として自分を呼びだす 1. 再帰とは、自分自身を呼び出す関数である 2. 関数の最初に「終端条件」を記述する 3. 「解きたい問題より小さな問題」に分解して自分自身を呼び出す
  21. 21 def fact(n): if n == 1: return 1 return

    n * fact(n-1) fact(3) fact(2) fact(1) 呼び出し 呼び出し ここで終端条件にマッチ fact(1) = 1 fact(2) = 2 * fact(1) fact(3)ください fact(3) = 3 * fact(2) = 6 再帰は「行って帰って」来る
  22. 22 1. 再帰とは、自分自身を呼び出す関数である 2. 関数の最初に「終端条件」を記述する 3. 「解きたい問題より小さな問題」に分解して 自分自身を呼び出す 再帰三カ条 再帰は「行って帰って」来る

    fact(3) fact(2) fact(1) 呼び出し 呼び出し ここで終端条件にマッチ fact(1) = 1 fact(2) = 2 * fact(1) fact(3)ください fact(3) = 3 * fact(2) = 6
  23. 23 3 = 1 + 1 + 1 3 =

    1 + 2 3 = 2 + 1 n段の階段を1段もしくは2段を混ぜて登る時、何通りの登り方があるか? n段の階段の登り方の数を返す関数 kaidan(n)が欲しい
  24. 24 3 = 1 + 1 + 1 3 =

    1 + 2 3 = 2 + 1 整数nを、1や2の和として表す方法の数 3 = 1 + 1 + 1 3 = 1 + 2 3 = 2 + 1 4 = 1 + 1 + 1 + 1 4 = 1 + 1 + 2 4 = 1 + 2 + 1 4 = 2 + 1 + 1 4 = 2 + 2 kaidan(3) = 3 kaidan(4) = 5
  25. 25 再帰の考え方 「今解きたい問題よりも小さな問題の答えが全 てわかっている場合、解きたい問題の答えはど う記述できるだろうか?」 階段を登り切る時は、最後に1段登る場合と2段登る場合がある n n-1 n-2 n

    n-1 n-2 kaidan(n) = kaidan(n-1) + kaidan(n-2)
  26. 26 再帰呼び出しには、必ず終端条件が必要 階段の段数が1段や2段の場合には値を返す def kaidan(n): # 終端条件 if 条件: return

    値 # 再帰部分 return 自分自身を使った式 最終的に関数はこんな形になる 終端条件が二つあることに注意すること
  27. 27 迷路が与えられた時、スタートからゴールまでの道を知りたい • とりあえず進んで見る • 分かれ道に来たら、現在位置を覚えて適当に進む • もし行き止まりなら、先程の場所まで戻って別の道を試す 基本的なアルゴリズム このように「とりあえず試して、ダメならやりなおす」

    というアルゴリズムをバックトラックと呼ぶ
  28. 28 とりあえず片方を試してみて、ダメなら戻る 1 2 3 4 5 6 7 将棋や囲碁の思考ルーチンに使われる

    数独等では「仮置き」と呼ばれる
  29. 29 1. 分かれ道に来た 2. とりあえず片方に進んで見る 3. 行き止まりだったので戻る 4. まだ試してない道があれば進む

  30. 30 0 1 2 0 1 2 3 3 5

    4 5 6 6 7 1. スタートからの距離を記録 2. 距離地図が完成する 0 1 2 3 3 5 4 5 6 6 7 0 1 2 3 3 5 4 5 6 6 7 3. ゴールからカウントダウン 4. スタート地点まで到達したら完成