SlideShare a Scribd company logo
1 of 33
Download to read offline
純粋関数型アルゴリズム入門

  日本ユニシス株式会社
   総合技術研究所
     加藤公一
まずは簡単に自己紹介
ツイッター界隈での認識




                           私



              一時期10位以内にいたことも・・・




田中さん
でもインチキHaskellerです


  実はあまリHaskellのコード書いたことないですし・・・
なので我田引水
 アルゴリズムの話をします
今日の話
この本の解説                 Purely Functional
                       Data Structure

                       Chris Okazaki




         リストとキューの話しかしません
         (それでも十分難しい)
関数型言語の利点
• 本を読め! by C.Okazaki
  – J.Backus 1978
  – J.Hughes 1989
  – P.Hudak and M.P. Jones 1994
• それだとあんまりなので、適宜説明しま
  す
データ永続性(persistency)
• 変数に割り当てられた値は一切変更され
  ることはない
 – 破壊的代入が行われない
 – いつ参照しても同じ値が返ってくる
• 永続性により保守性が高まる
     例:
     1. aにある値を代入
     2. bにある値を代入
     3. a,bの値を表示
     4. aとbにある操作をしてその結果をcに代入
     5. a,bの値を表示


      この間に値が変わらないのが、永続性
純粋関数型データ構造
    (アルゴリズム)
• データの永続性が保証されるデータ構造
  (アルゴリズム)である
• つまり永続性による保守性と、計算効率
  を同時に考慮する
例:リストの結合
                xs=[1; 2; 3; 4]
                ys=[5; 6; 7; 8]
                zs=xs++ys

手続き型言語(たとえばC言語)では?

xs                        ys


1    2      3     4       5       6   7   8


zs
          これだと、実行後xsの値が書き変わってしまう
          (永続的ではない)

         永続性の保証のためには、事前にデータのコピーが必要
純粋関数型アルゴリズム
               すべてをコピーする必要はない!

xs                         ys


1     2        3     4      5     6   7   8


xs’


1     2        3     4

                   片方だけコピーすればよい
zs
                   通常     純粋関数型
          計算       O(1)   O(n)
          量:
                   損している?→もっといい方法がある(後で説明)
純粋関数型アルゴリズムを
     学ぶメリット
• (非純粋)関数型言語を使っている人:
  一部を純粋関数型にすることで保守性を
  高めることができる
• 純粋関数型言語を使っている人:計算効
  率の良いプログラムが書ける
• 手続き型言語を使っている人:保守性を
  高めることができる
 – 解く問題によっては・・・
以下の疑似コード表記ルール
• 遅延評価がデフォルトだとみなしたくな
  いので、ML風に疑似コードを書きます
 – アルゴリズムを明示的に理解するため
 – MLを知らない人でも大丈夫です。多分読めま
   す。
• Haskellのハラワタを示していると解釈して
  もいい
準備:リストの基本操作
          a=[1;2;3]

head a => 1       a       1       2       3

                          1

b=tail a => [2;3]
                          a   1       2       3

                                      b
c=Cons(0,a) => [0;1;2;3]
              c       0       1       2       3

                              a

        すべて永続性を保持しても計算量O(1)
ならし計算量
    (Amortized Complexity)
• 一連の操作の中で、ならして(平均的
  な)計算量を考える
• 一連の操作の中で一部計算量が多いこと
  があったとしても、平均すると計算量が
  小さいということがある
例:キュー(queue)
• 先入れ先出しリスト
• ここでは以下の3つの操作を考える
 – head:キューの最初の値を取得する
 – tail:キューから最初の値を削除する
 – snoc:キューに値を追加する
                 snoc 1
                 snoc 2
                 snoc 3
                 head => 1
                 tail
                 head => 2
                 head => 2
純粋関数型なキューのアルゴリズ
       ム
• キューを2つのリストの組(f,r)として表す
 – ただし、常にfが空にならないように管理する
 – fが空になった時は、(reverse r, [])を返す
• 新しく値を加える(snoc)ときは、rの頭
  に加える
• 値を取得する(head)ときは、fの頭の値
  を取得する
• 値を削除する(tail)ときは、fの頭を削除
  する
通常のリストによる表現                       純粋関数型データ構造


              q1=snoc (empty,1)
                                   ([], [1])
  [1]
                                   ([1], [])
              q2=snoc (q1,2)
              q3=snoc (q2,3)
              q4=snoc (q3,4)
  [1;2;3;4]                       ([1], [4;3;2])

              q5=tail q4
                                  ([], [4;3;2])
  [2;3;4]
                                  ([2;3;4], [])
              q6=tail q5

  [3;4]                           ([3;4], [])
              q7=snoc q6 5

  [3;4;5]                         ([3;4], [5])
計算量
• reverse rの計算量が大きい:rのサイズmと
  するとO(m)
• しかしreverseはたまにしか起こらないの
  で、ならすと大きな計算量増加にはなら
  ない→ならし計算量の考え方
詳細な解析
• snocの計算量は1(rの先頭に要素を加える
  だけ)
• tailの計算量は
 – 通常は1(fのtailをとる)
 – fの要素数が1のときはm+1(fのtailを取ってか
   らrのreverse)
ならし計算量
• snocの計算量は2だと思う(実際には1なの
  で、1貯金する)
• tailの計算量は
 – 通常は1
 – fの要素数が1のときは貯金を使って1(rのサ
   イズがmになるまではsnocがm回行われている
   →貯金はmある)
• つまり、ならせばすべての操作の計算量
  はO(1)であるとみなしてよい
銀行家法(Banker’s Method)
• このように、実際にかかっていない計算
  量をかかったとみなして貯金し、必要に
  応じて(大きな計算量が必要なときに)
  その貯金を使うという考え方を、銀行家
  法と呼ぶ。
ここまでのまとめ
• ならし計算量でみると、キューの操作の
  計算量は、純粋関数型でもO(1)
• ここでの計算量評価法は「銀行家法」が
  使われた
 – ほかには物理学者法(Physicist’s method)があ
   る
• でもなんかだまされたような気がす
  る・・・
遅延評価(Lazy evaluation)
•   実際に必要になるまで評価は行わない
•   代入時点では「式」を覚えている
•   一度評価されたら値を覚えている
•   Haskellではデフォルトの動作
記法
• 既存関数を遅延評価するときは頭に$を付
  ける
• 遅延評価する関数を新たに定義するとき
  は、関数名の前にlazyを付ける
• 強制的に評価するときには、force関数を
  適用 例:n番目の素数を返す関数primes n
     val p=$primes 1000000   一瞬で終わる(計算しない)
     val q=force p           時間がかかる
     val r=force p           一瞬で終わる(答を覚えている)
遅延付きリスト(ストリーム)
     ~アイデア~
• リストの結合は最終的な目的ではない
• 通常リストについての操作で最終的な目
  的は、リストの一部を表示または他の計
  算に使うこと
• 以下、2つのリストを結合した後にtake k
  (最初のk個の要素をとる)をするという
  ストーリを考える
リストはConsの遅延で表現する

   val p=$Cons(1,$Cons(2,$Cons(3,$Cons(4,$Nil))))
                              1       2        3        4


   val q=$Cons(4,$Cons(5,$Cons(6,$Cons(7,$Nil))))
                              4       5        6        7



   fun lazy ($Nil)++t=t
          | ($Cons(x,s))++t=$Cons(x,s++t)

   fun lazy take(0,s) = $Nil
          | take(n,$Nil) = $Nil
          | take(n,$Cons(x,s)) = $Cons(x,take(n-1,s))
fun lazy ($Nil)++t=t
                                    | ($Cons(x,s))++t=$Cons(x,s++t)

                             fun lazy take(0,s) = $Nil
                                    | take(n,$Nil) = $Nil
                                    | take(n,$Cons(x,s)) = $Cons(x,take(n-1,s))




val p=$Cons(1,$Cons(2,$Cons(3,$Cons(4,$Nil))))

val q=$Cons(4,$Cons(5,$Cons(6,$Cons(7,$Nil))))

val r=take(2,p++q)           val s=force r

take(2, $Cons(1,$Cons(2,$Cons(3,$Cons(4,$Nil))))
          ++$Cons(4,$Cons(5,$Cons(6,$Cons(7,$Nil)))))
=> take(2, $Cons(1,$Cons(2,$Cons(3,$Cons(4,$Nil)))
                   ++$Cons(4,$Cons(5,$Cons(6,$Cons(7,$Nil))))))
=> $Cons(1,take(1,$Cons(2,$Cons(3,$Cons(4,$Nil)))
                   ++$Cons(4,$Cons(5,$Cons(6,$Cons(7,$Nil))))))
=> $Cons(1,take(1,$Cons(2,$Cons(3,$Cons(4,$Nil))
                   ++$Cons(4,$Cons(5,$Cons(6,$Cons(7,$Nil)))))))
=> $Cons(1,$Cons(2,take(0,$Cons(3,$Cons(4,$Nil))
                   ++$Cons(4,$Cons(5,$Cons(6,$Cons(7,$Nil)))))))
=> $Cons(1,$Cons(2,$Nil)
計算量
• 結合(++)してtake kする計算量は、純粋
  関数型でもO(k)
• 結合対象のリストのサイズには依存しな
  い
キューの遅延評価版
• キューは、遅延評価版を考えることで、
  「ならし」の部分が消滅する
 – つまり、ならさなくてもO(1)に
基本的アイデア
• reverseの遅延評価版「rotate」を考える
• rのサイズがfのサイズより1大きいときに
  限ってrotateが動くこととする
 – 非遅延版はf=[]のときにreverseが走った
 – 今度はf++reverse rを計算したい
• しかしそのまま直接では、遅延評価版を
  作れないので、アキュムレータを入れる
            (f,r,a)のタプルを考える
 fun rotate ($Nil, Cons(y,_), a)=$Cons(y,a)
   | rotate ($Cons(x,xs), Cons(y,ys), a)    注:rについては非遅延リストでいい
      =$Cons(x,rotate(xs,ys,$Cons(y,a)))
例                                 fun rotate ($Nil, Cons(y,_), a)=$Cons(y,a)
                                    | rotate ($Cons(x,xs), $Cons(y,ys), a)
                                       =$Cons(x,rotate(xs,ys,$Cons(y,a)))

    f=[1;2], r=[5;4;3]   の場合

    f2=rotate($Cons(1,$Cons(2,$Nil)), [5;4;3], $Nil)
     => $Cons(1, rotate($Cons(2,$Nil),[4;3],$Cons(5,$Nil))) ここで停止する


    次にtailをとると・・・
    f3=tail f2
    =>rotate($Cons(2,$Nil),[4;3],$Cons(5,$Nil))
    =>$Cons(2, rotate($Nil,[3],$Cons(4,$Cons(5,$Nil)))) ここで停止する


    またまたtailをとると・・・
    f4=tail f3
    =>rotate($Nil,[3],$Cons(4,$Cons(5,$Nil)))
    =>$Cons(3,$Cons(4,$Cons(5,$Nil)))
                                     ここで停止する

     以下tailをとる操作は自明
                            以上のようなrotateを部品として使う
                            ほかにも工夫が必要だが、説明略
まとめ
• 純粋関数型アルゴリズムは便利
 – 計算は速いし、保守性も高い
 – もちろん多少の犠牲(オーバーヘッド)は伴
   う
• 純粋関数型アルゴリズムを設計するうえ
  で遅延評価は重要
 – 計算量に直接効いてくる
 – ならし計算量がならさなくてもよくなる
   (deamortalization)

More Related Content

What's hot

たのしい高階関数
たのしい高階関数たのしい高階関数
たのしい高階関数Shinichi Kozake
 
プログラミングコンテストでの動的計画法
プログラミングコンテストでの動的計画法プログラミングコンテストでの動的計画法
プログラミングコンテストでの動的計画法Takuya Akiba
 
Re永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライドRe永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライドMasaki Hara
 
関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCaml関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCamlHaruka Oikawa
 
プログラミングコンテストでの乱択アルゴリズム
プログラミングコンテストでの乱択アルゴリズムプログラミングコンテストでの乱択アルゴリズム
プログラミングコンテストでの乱択アルゴリズムTakuya Akiba
 
SAT/SMTソルバの仕組み
SAT/SMTソルバの仕組みSAT/SMTソルバの仕組み
SAT/SMTソルバの仕組みMasahiro Sakai
 
冬のLock free祭り safe
冬のLock free祭り safe冬のLock free祭り safe
冬のLock free祭り safeKumazaki Hiroki
 
謎の言語Forthが謎なので実装した
謎の言語Forthが謎なので実装した謎の言語Forthが謎なので実装した
謎の言語Forthが謎なので実装したt-sin
 
競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性Hibiki Yamashiro
 
暗号文のままで計算しよう - 準同型暗号入門 -
暗号文のままで計算しよう - 準同型暗号入門 -暗号文のままで計算しよう - 準同型暗号入門 -
暗号文のままで計算しよう - 準同型暗号入門 -MITSUNARI Shigeo
 
C++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプC++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプKohsuke Yuasa
 
二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方
二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方
二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方Kensuke Otsuki
 
指数時間アルゴリズム入門
指数時間アルゴリズム入門指数時間アルゴリズム入門
指数時間アルゴリズム入門Yoichi Iwata
 
Union find(素集合データ構造)
Union find(素集合データ構造)Union find(素集合データ構造)
Union find(素集合データ構造)AtCoder Inc.
 
オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?Moriharu Ohzu
 
クソザコ鳥頭が非順序連想コンテナに入門してみた
クソザコ鳥頭が非順序連想コンテナに入門してみたクソザコ鳥頭が非順序連想コンテナに入門してみた
クソザコ鳥頭が非順序連想コンテナに入門してみたMitsuru Kariya
 

What's hot (20)

たのしい高階関数
たのしい高階関数たのしい高階関数
たのしい高階関数
 
プログラミングコンテストでの動的計画法
プログラミングコンテストでの動的計画法プログラミングコンテストでの動的計画法
プログラミングコンテストでの動的計画法
 
Re永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライドRe永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライド
 
関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCaml関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCaml
 
明日使えないすごいビット演算
明日使えないすごいビット演算明日使えないすごいビット演算
明日使えないすごいビット演算
 
プログラミングコンテストでの乱択アルゴリズム
プログラミングコンテストでの乱択アルゴリズムプログラミングコンテストでの乱択アルゴリズム
プログラミングコンテストでの乱択アルゴリズム
 
プログラムを高速化する話
プログラムを高速化する話プログラムを高速化する話
プログラムを高速化する話
 
SAT/SMTソルバの仕組み
SAT/SMTソルバの仕組みSAT/SMTソルバの仕組み
SAT/SMTソルバの仕組み
 
冬のLock free祭り safe
冬のLock free祭り safe冬のLock free祭り safe
冬のLock free祭り safe
 
C++ マルチスレッド 入門
C++ マルチスレッド 入門C++ マルチスレッド 入門
C++ マルチスレッド 入門
 
謎の言語Forthが謎なので実装した
謎の言語Forthが謎なので実装した謎の言語Forthが謎なので実装した
謎の言語Forthが謎なので実装した
 
競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性
 
暗号文のままで計算しよう - 準同型暗号入門 -
暗号文のままで計算しよう - 準同型暗号入門 -暗号文のままで計算しよう - 準同型暗号入門 -
暗号文のままで計算しよう - 準同型暗号入門 -
 
C++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプC++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプ
 
直交領域探索
直交領域探索直交領域探索
直交領域探索
 
二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方
二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方
二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方
 
指数時間アルゴリズム入門
指数時間アルゴリズム入門指数時間アルゴリズム入門
指数時間アルゴリズム入門
 
Union find(素集合データ構造)
Union find(素集合データ構造)Union find(素集合データ構造)
Union find(素集合データ構造)
 
オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?
 
クソザコ鳥頭が非順序連想コンテナに入門してみた
クソザコ鳥頭が非順序連想コンテナに入門してみたクソザコ鳥頭が非順序連想コンテナに入門してみた
クソザコ鳥頭が非順序連想コンテナに入門してみた
 

Similar to 純粋関数型アルゴリズム入門

文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜Takeshi Arabiki
 
すごいHaskell読書会#1 in 大阪
すごいHaskell読書会#1 in 大阪すごいHaskell読書会#1 in 大阪
すごいHaskell読書会#1 in 大阪yashigani
 
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜Hiromi Ishii
 
Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2Ransui Iso
 
Chapter 6: Computing on the language (R Language Definition)
Chapter 6: Computing on the language (R Language Definition)Chapter 6: Computing on the language (R Language Definition)
Chapter 6: Computing on the language (R Language Definition)Nagi Teramo
 
Haskell勉強会 in ie
Haskell勉強会 in ieHaskell勉強会 in ie
Haskell勉強会 in iemaeken2010
 
Lisp Tutorial for Pythonista : Day 5
Lisp Tutorial for Pythonista : Day 5Lisp Tutorial for Pythonista : Day 5
Lisp Tutorial for Pythonista : Day 5Ransui Iso
 
Clojure programming-chapter-2
Clojure programming-chapter-2Clojure programming-chapter-2
Clojure programming-chapter-2Masao Kato
 
「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」
「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」
「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」Nagi Teramo
 
12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと
12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと 12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと
12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと Haruka Ozaki
 
(Ruby使いのための)Scalaで学ぶ関数型プログラミング
(Ruby使いのための)Scalaで学ぶ関数型プログラミング(Ruby使いのための)Scalaで学ぶ関数型プログラミング
(Ruby使いのための)Scalaで学ぶ関数型プログラミングOuka Yuka
 
Material
MaterialMaterial
Material_TUNE_
 
Python勉強会3-コレクションとファイル
Python勉強会3-コレクションとファイルPython勉強会3-コレクションとファイル
Python勉強会3-コレクションとファイル理 小林
 
プログラミングHaskell(第1章)
プログラミングHaskell(第1章)プログラミングHaskell(第1章)
プログラミングHaskell(第1章)yaju88
 
Real World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみたReal World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみたblackenedgold
 
JOIss2020 発表資料
JOIss2020 発表資料JOIss2020 発表資料
JOIss2020 発表資料mdkcpp 1015
 

Similar to 純粋関数型アルゴリズム入門 (20)

文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
 
すごいHaskell読書会#1 in 大阪
すごいHaskell読書会#1 in 大阪すごいHaskell読書会#1 in 大阪
すごいHaskell読書会#1 in 大阪
 
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
 
Pythonintro
PythonintroPythonintro
Pythonintro
 
Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2
 
Chapter 6: Computing on the language (R Language Definition)
Chapter 6: Computing on the language (R Language Definition)Chapter 6: Computing on the language (R Language Definition)
Chapter 6: Computing on the language (R Language Definition)
 
Haskell勉強会 in ie
Haskell勉強会 in ieHaskell勉強会 in ie
Haskell勉強会 in ie
 
Lisp Tutorial for Pythonista : Day 5
Lisp Tutorial for Pythonista : Day 5Lisp Tutorial for Pythonista : Day 5
Lisp Tutorial for Pythonista : Day 5
 
Clojure programming-chapter-2
Clojure programming-chapter-2Clojure programming-chapter-2
Clojure programming-chapter-2
 
「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」
「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」
「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」
 
12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと
12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと 12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと
12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと
 
(Ruby使いのための)Scalaで学ぶ関数型プログラミング
(Ruby使いのための)Scalaで学ぶ関数型プログラミング(Ruby使いのための)Scalaで学ぶ関数型プログラミング
(Ruby使いのための)Scalaで学ぶ関数型プログラミング
 
勉強会課題①
勉強会課題①勉強会課題①
勉強会課題①
 
Material
MaterialMaterial
Material
 
Python勉強会3-コレクションとファイル
Python勉強会3-コレクションとファイルPython勉強会3-コレクションとファイル
Python勉強会3-コレクションとファイル
 
Python opt
Python optPython opt
Python opt
 
WUPC2012
WUPC2012WUPC2012
WUPC2012
 
プログラミングHaskell(第1章)
プログラミングHaskell(第1章)プログラミングHaskell(第1章)
プログラミングHaskell(第1章)
 
Real World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみたReal World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみた
 
JOIss2020 発表資料
JOIss2020 発表資料JOIss2020 発表資料
JOIss2020 発表資料
 

More from Kimikazu Kato

Tokyo webmining 2017-10-28
Tokyo webmining 2017-10-28Tokyo webmining 2017-10-28
Tokyo webmining 2017-10-28Kimikazu Kato
 
機械学習ゴリゴリ派のための数学とPython
機械学習ゴリゴリ派のための数学とPython機械学習ゴリゴリ派のための数学とPython
機械学習ゴリゴリ派のための数学とPythonKimikazu Kato
 
Pythonを使った機械学習の学習
Pythonを使った機械学習の学習Pythonを使った機械学習の学習
Pythonを使った機械学習の学習Kimikazu Kato
 
Fast and Probvably Seedings for k-Means
Fast and Probvably Seedings for k-MeansFast and Probvably Seedings for k-Means
Fast and Probvably Seedings for k-MeansKimikazu Kato
 
Pythonで機械学習入門以前
Pythonで機械学習入門以前Pythonで機械学習入門以前
Pythonで機械学習入門以前Kimikazu Kato
 
Pythonによる機械学習
Pythonによる機械学習Pythonによる機械学習
Pythonによる機械学習Kimikazu Kato
 
Introduction to behavior based recommendation system
Introduction to behavior based recommendation systemIntroduction to behavior based recommendation system
Introduction to behavior based recommendation systemKimikazu Kato
 
Pythonによる機械学習の最前線
Pythonによる機械学習の最前線Pythonによる機械学習の最前線
Pythonによる機械学習の最前線Kimikazu Kato
 
Sparse pca via bipartite matching
Sparse pca via bipartite matchingSparse pca via bipartite matching
Sparse pca via bipartite matchingKimikazu Kato
 
正しいプログラミング言語の覚え方
正しいプログラミング言語の覚え方正しいプログラミング言語の覚え方
正しいプログラミング言語の覚え方Kimikazu Kato
 
Introduction to NumPy for Machine Learning Programmers
Introduction to NumPy for Machine Learning ProgrammersIntroduction to NumPy for Machine Learning Programmers
Introduction to NumPy for Machine Learning ProgrammersKimikazu Kato
 
Recommendation System --Theory and Practice
Recommendation System --Theory and PracticeRecommendation System --Theory and Practice
Recommendation System --Theory and PracticeKimikazu Kato
 
A Safe Rule for Sparse Logistic Regression
A Safe Rule for Sparse Logistic RegressionA Safe Rule for Sparse Logistic Regression
A Safe Rule for Sparse Logistic RegressionKimikazu Kato
 
特定の不快感を与えるツイートの分類と自動生成について
特定の不快感を与えるツイートの分類と自動生成について特定の不快感を与えるツイートの分類と自動生成について
特定の不快感を与えるツイートの分類と自動生成についてKimikazu Kato
 
Effective Numerical Computation in NumPy and SciPy
Effective Numerical Computation in NumPy and SciPyEffective Numerical Computation in NumPy and SciPy
Effective Numerical Computation in NumPy and SciPyKimikazu Kato
 
【論文紹介】Approximate Bayesian Image Interpretation Using Generative Probabilisti...
【論文紹介】Approximate Bayesian Image Interpretation Using Generative Probabilisti...【論文紹介】Approximate Bayesian Image Interpretation Using Generative Probabilisti...
【論文紹介】Approximate Bayesian Image Interpretation Using Generative Probabilisti...Kimikazu Kato
 
About Our Recommender System
About Our Recommender SystemAbout Our Recommender System
About Our Recommender SystemKimikazu Kato
 

More from Kimikazu Kato (20)

Tokyo webmining 2017-10-28
Tokyo webmining 2017-10-28Tokyo webmining 2017-10-28
Tokyo webmining 2017-10-28
 
機械学習ゴリゴリ派のための数学とPython
機械学習ゴリゴリ派のための数学とPython機械学習ゴリゴリ派のための数学とPython
機械学習ゴリゴリ派のための数学とPython
 
Pythonを使った機械学習の学習
Pythonを使った機械学習の学習Pythonを使った機械学習の学習
Pythonを使った機械学習の学習
 
Fast and Probvably Seedings for k-Means
Fast and Probvably Seedings for k-MeansFast and Probvably Seedings for k-Means
Fast and Probvably Seedings for k-Means
 
Pythonで機械学習入門以前
Pythonで機械学習入門以前Pythonで機械学習入門以前
Pythonで機械学習入門以前
 
Pythonによる機械学習
Pythonによる機械学習Pythonによる機械学習
Pythonによる機械学習
 
Introduction to behavior based recommendation system
Introduction to behavior based recommendation systemIntroduction to behavior based recommendation system
Introduction to behavior based recommendation system
 
Pythonによる機械学習の最前線
Pythonによる機械学習の最前線Pythonによる機械学習の最前線
Pythonによる機械学習の最前線
 
Sparse pca via bipartite matching
Sparse pca via bipartite matchingSparse pca via bipartite matching
Sparse pca via bipartite matching
 
正しいプログラミング言語の覚え方
正しいプログラミング言語の覚え方正しいプログラミング言語の覚え方
正しいプログラミング言語の覚え方
 
養成読本と私
養成読本と私養成読本と私
養成読本と私
 
Introduction to NumPy for Machine Learning Programmers
Introduction to NumPy for Machine Learning ProgrammersIntroduction to NumPy for Machine Learning Programmers
Introduction to NumPy for Machine Learning Programmers
 
Recommendation System --Theory and Practice
Recommendation System --Theory and PracticeRecommendation System --Theory and Practice
Recommendation System --Theory and Practice
 
A Safe Rule for Sparse Logistic Regression
A Safe Rule for Sparse Logistic RegressionA Safe Rule for Sparse Logistic Regression
A Safe Rule for Sparse Logistic Regression
 
特定の不快感を与えるツイートの分類と自動生成について
特定の不快感を与えるツイートの分類と自動生成について特定の不快感を与えるツイートの分類と自動生成について
特定の不快感を与えるツイートの分類と自動生成について
 
Effective Numerical Computation in NumPy and SciPy
Effective Numerical Computation in NumPy and SciPyEffective Numerical Computation in NumPy and SciPy
Effective Numerical Computation in NumPy and SciPy
 
Sapporo20140709
Sapporo20140709Sapporo20140709
Sapporo20140709
 
【論文紹介】Approximate Bayesian Image Interpretation Using Generative Probabilisti...
【論文紹介】Approximate Bayesian Image Interpretation Using Generative Probabilisti...【論文紹介】Approximate Bayesian Image Interpretation Using Generative Probabilisti...
【論文紹介】Approximate Bayesian Image Interpretation Using Generative Probabilisti...
 
Zuang-FPSGD
Zuang-FPSGDZuang-FPSGD
Zuang-FPSGD
 
About Our Recommender System
About Our Recommender SystemAbout Our Recommender System
About Our Recommender System
 

Recently uploaded

2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~arts yokohama
 
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見Shumpei Kishi
 
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdfTaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdfMatsushita Laboratory
 
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法ssuser370dd7
 
20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdf20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdfAyachika Kitazaki
 
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)ssuser539845
 
2024 01 Virtual_Counselor
2024 01 Virtual_Counselor 2024 01 Virtual_Counselor
2024 01 Virtual_Counselor arts yokohama
 
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-LoopへTetsuya Nihonmatsu
 

Recently uploaded (11)

2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
 
2024 03 CTEA
2024 03 CTEA2024 03 CTEA
2024 03 CTEA
 
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
 
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdfTaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
 
What is the world where you can make your own semiconductors?
What is the world where you can make your own semiconductors?What is the world where you can make your own semiconductors?
What is the world where you can make your own semiconductors?
 
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
 
20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdf20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdf
 
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
 
2024 01 Virtual_Counselor
2024 01 Virtual_Counselor 2024 01 Virtual_Counselor
2024 01 Virtual_Counselor
 
2024 04 minnanoito
2024 04 minnanoito2024 04 minnanoito
2024 04 minnanoito
 
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
 

純粋関数型アルゴリズム入門

  • 3. ツイッター界隈での認識 私 一時期10位以内にいたことも・・・ 田中さん
  • 6. 今日の話 この本の解説 Purely Functional Data Structure Chris Okazaki リストとキューの話しかしません (それでも十分難しい)
  • 7. 関数型言語の利点 • 本を読め! by C.Okazaki – J.Backus 1978 – J.Hughes 1989 – P.Hudak and M.P. Jones 1994 • それだとあんまりなので、適宜説明しま す
  • 8. データ永続性(persistency) • 変数に割り当てられた値は一切変更され ることはない – 破壊的代入が行われない – いつ参照しても同じ値が返ってくる • 永続性により保守性が高まる 例: 1. aにある値を代入 2. bにある値を代入 3. a,bの値を表示 4. aとbにある操作をしてその結果をcに代入 5. a,bの値を表示 この間に値が変わらないのが、永続性
  • 9. 純粋関数型データ構造 (アルゴリズム) • データの永続性が保証されるデータ構造 (アルゴリズム)である • つまり永続性による保守性と、計算効率 を同時に考慮する
  • 10. 例:リストの結合 xs=[1; 2; 3; 4] ys=[5; 6; 7; 8] zs=xs++ys 手続き型言語(たとえばC言語)では? xs ys 1 2 3 4 5 6 7 8 zs これだと、実行後xsの値が書き変わってしまう (永続的ではない) 永続性の保証のためには、事前にデータのコピーが必要
  • 11. 純粋関数型アルゴリズム すべてをコピーする必要はない! xs ys 1 2 3 4 5 6 7 8 xs’ 1 2 3 4 片方だけコピーすればよい zs 通常 純粋関数型 計算 O(1) O(n) 量: 損している?→もっといい方法がある(後で説明)
  • 12. 純粋関数型アルゴリズムを 学ぶメリット • (非純粋)関数型言語を使っている人: 一部を純粋関数型にすることで保守性を 高めることができる • 純粋関数型言語を使っている人:計算効 率の良いプログラムが書ける • 手続き型言語を使っている人:保守性を 高めることができる – 解く問題によっては・・・
  • 13. 以下の疑似コード表記ルール • 遅延評価がデフォルトだとみなしたくな いので、ML風に疑似コードを書きます – アルゴリズムを明示的に理解するため – MLを知らない人でも大丈夫です。多分読めま す。 • Haskellのハラワタを示していると解釈して もいい
  • 14. 準備:リストの基本操作 a=[1;2;3] head a => 1 a 1 2 3 1 b=tail a => [2;3] a 1 2 3 b c=Cons(0,a) => [0;1;2;3] c 0 1 2 3 a すべて永続性を保持しても計算量O(1)
  • 15. ならし計算量 (Amortized Complexity) • 一連の操作の中で、ならして(平均的 な)計算量を考える • 一連の操作の中で一部計算量が多いこと があったとしても、平均すると計算量が 小さいということがある
  • 16. 例:キュー(queue) • 先入れ先出しリスト • ここでは以下の3つの操作を考える – head:キューの最初の値を取得する – tail:キューから最初の値を削除する – snoc:キューに値を追加する snoc 1 snoc 2 snoc 3 head => 1 tail head => 2 head => 2
  • 17. 純粋関数型なキューのアルゴリズ ム • キューを2つのリストの組(f,r)として表す – ただし、常にfが空にならないように管理する – fが空になった時は、(reverse r, [])を返す • 新しく値を加える(snoc)ときは、rの頭 に加える • 値を取得する(head)ときは、fの頭の値 を取得する • 値を削除する(tail)ときは、fの頭を削除 する
  • 18. 通常のリストによる表現 純粋関数型データ構造 q1=snoc (empty,1) ([], [1]) [1] ([1], []) q2=snoc (q1,2) q3=snoc (q2,3) q4=snoc (q3,4) [1;2;3;4] ([1], [4;3;2]) q5=tail q4 ([], [4;3;2]) [2;3;4] ([2;3;4], []) q6=tail q5 [3;4] ([3;4], []) q7=snoc q6 5 [3;4;5] ([3;4], [5])
  • 19. 計算量 • reverse rの計算量が大きい:rのサイズmと するとO(m) • しかしreverseはたまにしか起こらないの で、ならすと大きな計算量増加にはなら ない→ならし計算量の考え方
  • 20. 詳細な解析 • snocの計算量は1(rの先頭に要素を加える だけ) • tailの計算量は – 通常は1(fのtailをとる) – fの要素数が1のときはm+1(fのtailを取ってか らrのreverse)
  • 21. ならし計算量 • snocの計算量は2だと思う(実際には1なの で、1貯金する) • tailの計算量は – 通常は1 – fの要素数が1のときは貯金を使って1(rのサ イズがmになるまではsnocがm回行われている →貯金はmある) • つまり、ならせばすべての操作の計算量 はO(1)であるとみなしてよい
  • 22. 銀行家法(Banker’s Method) • このように、実際にかかっていない計算 量をかかったとみなして貯金し、必要に 応じて(大きな計算量が必要なときに) その貯金を使うという考え方を、銀行家 法と呼ぶ。
  • 23. ここまでのまとめ • ならし計算量でみると、キューの操作の 計算量は、純粋関数型でもO(1) • ここでの計算量評価法は「銀行家法」が 使われた – ほかには物理学者法(Physicist’s method)があ る • でもなんかだまされたような気がす る・・・
  • 24. 遅延評価(Lazy evaluation) • 実際に必要になるまで評価は行わない • 代入時点では「式」を覚えている • 一度評価されたら値を覚えている • Haskellではデフォルトの動作
  • 25. 記法 • 既存関数を遅延評価するときは頭に$を付 ける • 遅延評価する関数を新たに定義するとき は、関数名の前にlazyを付ける • 強制的に評価するときには、force関数を 適用 例:n番目の素数を返す関数primes n val p=$primes 1000000 一瞬で終わる(計算しない) val q=force p 時間がかかる val r=force p 一瞬で終わる(答を覚えている)
  • 26. 遅延付きリスト(ストリーム) ~アイデア~ • リストの結合は最終的な目的ではない • 通常リストについての操作で最終的な目 的は、リストの一部を表示または他の計 算に使うこと • 以下、2つのリストを結合した後にtake k (最初のk個の要素をとる)をするという ストーリを考える
  • 27. リストはConsの遅延で表現する val p=$Cons(1,$Cons(2,$Cons(3,$Cons(4,$Nil)))) 1 2 3 4 val q=$Cons(4,$Cons(5,$Cons(6,$Cons(7,$Nil)))) 4 5 6 7 fun lazy ($Nil)++t=t | ($Cons(x,s))++t=$Cons(x,s++t) fun lazy take(0,s) = $Nil | take(n,$Nil) = $Nil | take(n,$Cons(x,s)) = $Cons(x,take(n-1,s))
  • 28. fun lazy ($Nil)++t=t | ($Cons(x,s))++t=$Cons(x,s++t) fun lazy take(0,s) = $Nil | take(n,$Nil) = $Nil | take(n,$Cons(x,s)) = $Cons(x,take(n-1,s)) val p=$Cons(1,$Cons(2,$Cons(3,$Cons(4,$Nil)))) val q=$Cons(4,$Cons(5,$Cons(6,$Cons(7,$Nil)))) val r=take(2,p++q) val s=force r take(2, $Cons(1,$Cons(2,$Cons(3,$Cons(4,$Nil)))) ++$Cons(4,$Cons(5,$Cons(6,$Cons(7,$Nil))))) => take(2, $Cons(1,$Cons(2,$Cons(3,$Cons(4,$Nil))) ++$Cons(4,$Cons(5,$Cons(6,$Cons(7,$Nil)))))) => $Cons(1,take(1,$Cons(2,$Cons(3,$Cons(4,$Nil))) ++$Cons(4,$Cons(5,$Cons(6,$Cons(7,$Nil)))))) => $Cons(1,take(1,$Cons(2,$Cons(3,$Cons(4,$Nil)) ++$Cons(4,$Cons(5,$Cons(6,$Cons(7,$Nil))))))) => $Cons(1,$Cons(2,take(0,$Cons(3,$Cons(4,$Nil)) ++$Cons(4,$Cons(5,$Cons(6,$Cons(7,$Nil))))))) => $Cons(1,$Cons(2,$Nil)
  • 29. 計算量 • 結合(++)してtake kする計算量は、純粋 関数型でもO(k) • 結合対象のリストのサイズには依存しな い
  • 30. キューの遅延評価版 • キューは、遅延評価版を考えることで、 「ならし」の部分が消滅する – つまり、ならさなくてもO(1)に
  • 31. 基本的アイデア • reverseの遅延評価版「rotate」を考える • rのサイズがfのサイズより1大きいときに 限ってrotateが動くこととする – 非遅延版はf=[]のときにreverseが走った – 今度はf++reverse rを計算したい • しかしそのまま直接では、遅延評価版を 作れないので、アキュムレータを入れる (f,r,a)のタプルを考える fun rotate ($Nil, Cons(y,_), a)=$Cons(y,a) | rotate ($Cons(x,xs), Cons(y,ys), a) 注:rについては非遅延リストでいい =$Cons(x,rotate(xs,ys,$Cons(y,a)))
  • 32. fun rotate ($Nil, Cons(y,_), a)=$Cons(y,a) | rotate ($Cons(x,xs), $Cons(y,ys), a) =$Cons(x,rotate(xs,ys,$Cons(y,a))) f=[1;2], r=[5;4;3] の場合 f2=rotate($Cons(1,$Cons(2,$Nil)), [5;4;3], $Nil) => $Cons(1, rotate($Cons(2,$Nil),[4;3],$Cons(5,$Nil))) ここで停止する 次にtailをとると・・・ f3=tail f2 =>rotate($Cons(2,$Nil),[4;3],$Cons(5,$Nil)) =>$Cons(2, rotate($Nil,[3],$Cons(4,$Cons(5,$Nil)))) ここで停止する またまたtailをとると・・・ f4=tail f3 =>rotate($Nil,[3],$Cons(4,$Cons(5,$Nil))) =>$Cons(3,$Cons(4,$Cons(5,$Nil))) ここで停止する 以下tailをとる操作は自明 以上のようなrotateを部品として使う ほかにも工夫が必要だが、説明略
  • 33. まとめ • 純粋関数型アルゴリズムは便利 – 計算は速いし、保守性も高い – もちろん多少の犠牲(オーバーヘッド)は伴 う • 純粋関数型アルゴリズムを設計するうえ で遅延評価は重要 – 計算量に直接効いてくる – ならし計算量がならさなくてもよくなる (deamortalization)