SlideShare uma empresa Scribd logo
1 de 33
純粋関数型アルゴリズム入門

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




                           私



              一時期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)

Mais conteúdo relacionado

Mais procurados

関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCaml関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCamlHaruka Oikawa
 
Introduction to Categorical Programming (Revised)
Introduction to Categorical Programming (Revised)Introduction to Categorical Programming (Revised)
Introduction to Categorical Programming (Revised)Masahiro Sakai
 
暗号文のままで計算しよう - 準同型暗号入門 -
暗号文のままで計算しよう - 準同型暗号入門 -暗号文のままで計算しよう - 準同型暗号入門 -
暗号文のままで計算しよう - 準同型暗号入門 -MITSUNARI Shigeo
 
プログラミングコンテストでのデータ構造
プログラミングコンテストでのデータ構造プログラミングコンテストでのデータ構造
プログラミングコンテストでのデータ構造Takuya Akiba
 
高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装MITSUNARI Shigeo
 
競技プログラミングのためのC++入門
競技プログラミングのためのC++入門競技プログラミングのためのC++入門
競技プログラミングのためのC++入門natrium11321
 
最小カットを使って「燃やす埋める問題」を解く
最小カットを使って「燃やす埋める問題」を解く最小カットを使って「燃やす埋める問題」を解く
最小カットを使って「燃やす埋める問題」を解くshindannin
 
圏論のモナドとHaskellのモナド
圏論のモナドとHaskellのモナド圏論のモナドとHaskellのモナド
圏論のモナドとHaskellのモナドYoshihiro Mizoguchi
 
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14Ryo Suzuki
 
中3女子でもわかる constexpr
中3女子でもわかる constexpr中3女子でもわかる constexpr
中3女子でもわかる constexprGenya Murakami
 
ウェーブレット木の世界
ウェーブレット木の世界ウェーブレット木の世界
ウェーブレット木の世界Preferred Networks
 
Rolling Hashを殺す話
Rolling Hashを殺す話Rolling Hashを殺す話
Rolling Hashを殺す話Nagisa Eto
 
DSIRNLP #3 LZ4 の速さの秘密に迫ってみる
DSIRNLP #3 LZ4 の速さの秘密に迫ってみるDSIRNLP #3 LZ4 の速さの秘密に迫ってみる
DSIRNLP #3 LZ4 の速さの秘密に迫ってみるAtsushi KOMIYA
 
複素数・四元数と図形の回転
複素数・四元数と図形の回転複素数・四元数と図形の回転
複素数・四元数と図形の回転Yoshihiro Mizoguchi
 
勉強か?趣味か?人生か?―プログラミングコンテストとは
勉強か?趣味か?人生か?―プログラミングコンテストとは勉強か?趣味か?人生か?―プログラミングコンテストとは
勉強か?趣味か?人生か?―プログラミングコンテストとはTakuya Akiba
 

Mais procurados (20)

関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCaml関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCaml
 
Introduction to Categorical Programming (Revised)
Introduction to Categorical Programming (Revised)Introduction to Categorical Programming (Revised)
Introduction to Categorical Programming (Revised)
 
直交領域探索
直交領域探索直交領域探索
直交領域探索
 
明日使えないすごいビット演算
明日使えないすごいビット演算明日使えないすごいビット演算
明日使えないすごいビット演算
 
暗号文のままで計算しよう - 準同型暗号入門 -
暗号文のままで計算しよう - 準同型暗号入門 -暗号文のままで計算しよう - 準同型暗号入門 -
暗号文のままで計算しよう - 準同型暗号入門 -
 
LLVM最適化のこつ
LLVM最適化のこつLLVM最適化のこつ
LLVM最適化のこつ
 
プログラミングコンテストでのデータ構造
プログラミングコンテストでのデータ構造プログラミングコンテストでのデータ構造
プログラミングコンテストでのデータ構造
 
高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装
 
競技プログラミングのためのC++入門
競技プログラミングのためのC++入門競技プログラミングのためのC++入門
競技プログラミングのためのC++入門
 
最小カットを使って「燃やす埋める問題」を解く
最小カットを使って「燃やす埋める問題」を解く最小カットを使って「燃やす埋める問題」を解く
最小カットを使って「燃やす埋める問題」を解く
 
Marp Tutorial
Marp TutorialMarp Tutorial
Marp Tutorial
 
圏論のモナドとHaskellのモナド
圏論のモナドとHaskellのモナド圏論のモナドとHaskellのモナド
圏論のモナドとHaskellのモナド
 
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
 
中3女子でもわかる constexpr
中3女子でもわかる constexpr中3女子でもわかる constexpr
中3女子でもわかる constexpr
 
ウェーブレット木の世界
ウェーブレット木の世界ウェーブレット木の世界
ウェーブレット木の世界
 
Rolling Hashを殺す話
Rolling Hashを殺す話Rolling Hashを殺す話
Rolling Hashを殺す話
 
DSIRNLP #3 LZ4 の速さの秘密に迫ってみる
DSIRNLP #3 LZ4 の速さの秘密に迫ってみるDSIRNLP #3 LZ4 の速さの秘密に迫ってみる
DSIRNLP #3 LZ4 の速さの秘密に迫ってみる
 
π計算
π計算π計算
π計算
 
複素数・四元数と図形の回転
複素数・四元数と図形の回転複素数・四元数と図形の回転
複素数・四元数と図形の回転
 
勉強か?趣味か?人生か?―プログラミングコンテストとは
勉強か?趣味か?人生か?―プログラミングコンテストとは勉強か?趣味か?人生か?―プログラミングコンテストとは
勉強か?趣味か?人生か?―プログラミングコンテストとは
 

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

関数プログラミング入門
関数プログラミング入門関数プログラミング入門
関数プログラミング入門Hideyuki Tanaka
 
プログラミングコンテストでのデータ構造 2 ~動的木編~
プログラミングコンテストでのデータ構造 2 ~動的木編~プログラミングコンテストでのデータ構造 2 ~動的木編~
プログラミングコンテストでのデータ構造 2 ~動的木編~Takuya Akiba
 
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜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
 
F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~Nobuhisa Koizumi
 
Material
MaterialMaterial
Material_TUNE_
 
Python勉強会3-コレクションとファイル
Python勉強会3-コレクションとファイルPython勉強会3-コレクションとファイル
Python勉強会3-コレクションとファイル理 小林
 

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

関数プログラミング入門
関数プログラミング入門関数プログラミング入門
関数プログラミング入門
 
プログラミングコンテストでのデータ構造 2 ~動的木編~
プログラミングコンテストでのデータ構造 2 ~動的木編~プログラミングコンテストでのデータ構造 2 ~動的木編~
プログラミングコンテストでのデータ構造 2 ~動的木編~
 
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
 
すごい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で学ぶ関数型プログラミング
 
F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~
 
勉強会課題①
勉強会課題①勉強会課題①
勉強会課題①
 
Material
MaterialMaterial
Material
 
Python勉強会3-コレクションとファイル
Python勉強会3-コレクションとファイルPython勉強会3-コレクションとファイル
Python勉強会3-コレクションとファイル
 
Python opt
Python optPython opt
Python opt
 
WUPC2012
WUPC2012WUPC2012
WUPC2012
 

Mais de 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
 

Mais de 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
 

Último

論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNetToru Tamaki
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Danieldanielhu54
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...Toru Tamaki
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A surveyToru Tamaki
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdftaisei2219
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Yuma Ohgami
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものですiPride Co., Ltd.
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略Ryo Sasaki
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムsugiuralab
 

Último (9)

論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Daniel
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システム
 

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

  • 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)