SlideShare uma empresa Scribd logo
1 de 50
Algebraic DP:
動的計画法を書きやすく
      石井 大海
自己紹介
•   石井 大海 (id:mr_konn / @mr_konn)

•   早稲田大学数学科三年

    •   集合論やモデル理論、圏論、代数学に興味

    •   函数型言語、定理証明系など形式手法にも興味

•   2010 Summer Intern から PFI でバイト中

    •   Haskell で Twitter やWebのクローラを書いている
今日のおはなし
•   朗報:Haskell の話じゃありません!

    •   が、Haskell を使います。

•   Algebraic Dynamic Programming (ADP)
    •   連続データに対する動的計画法の新しい
        設計・実装法

    •   バイオインフォマティクスの分野から
Table of Contents
•   動的計画法の復習

    •   動的計画法とは?

    •   動的計画法の例

•   ADP の紹介

    •   動的計画法の問題点

    •   ADP とは?──原理と例

    •   ADP の改良版

•   まとめ
動的計画法の復習
動的計画法とは?
動的計画法(どうてきけいかくほう、英: Dynamic
Programming, DP)は、コンピュータ科学の分野におい
て、ある最適化問題を複数の部分問題に分割して解く際
に、そこまでに求められている以上の最適解が求められ
ないような部分問題を切り捨てながら解いていく手法で
ある。分割統治法がトップダウン的な手法であるのに対
し、動的計画法はボトムアップ的な手法といえる。

                 ── 動的計画法 - Wikipedia
動的計画法とは?
動的計画法(どうてきけいかくほう、英: Dynamic
Programming, DP)は、コンピュータ科学の分野におい
て、ある最適化問題を複数の部分問題に分割して解く際
に、そこまでに求められている以上の最適解が求められ
ないような部分問題を切り捨てながら解いていく手法で
ある。分割統治法がトップダウン的な手法であるのに対
し、動的計画法はボトムアップ的な手法といえる。

                 ── 動的計画法 - Wikipedia
結局どういうこと?
•   小さい範囲の最適解を組み合わせて解ける最適
    化問題を

•   小さい部分での結果をメモ化しながら解く方法

    •   指数時間かかりそうなものがだいたい多項式
        時間で解けるようになる

•   部分問題と全体の漸化式で表わされ、アルゴリズ
    ムはメモ化行列への反復作業として記述される
動的計画法の例

• 編集距離
• 最長一致部分列
• 括弧の位置最適化
• 最長増加部分列
編集距離
•   入力:二つの文字列

•   出力:一方の文字列に文字を挿入・削除す
    ることで他方の文字列にするのに必要な最
    短手数

•   例:(darling, airline)

    •   4(darling→arling→airling→airlin→airline)
編集距離の考え方
•   入力:(a1a2...an, b1b2...bm)
    •   d[i, j] = a1...ai と b1...bj の編集距離
    •   d[i+1, j+1] の候補:
        •   ai+1 までを bj に編集して、bj+1を足す



        •   ai までを bj+1 に編集して、ai+1 を削る



        •   ai までを bj に編集して、ai+1を削ってbj+1を足す



        •   これらの中で最も手数が少ないもの
編集距離の漸化式



• これをメモ化して、i, j を 1 から埋めて
 再帰していく
実装例(Ruby)
def edit_distance(as, bs)
  n = as.length
  m = bs.length
  d = Hash.new {|h, k| h[k] = Hash.new(0)}
  for i in 0..n
    d[i][0] = i
  end
  for j in 0..m
    d[0][j] = j
  end
  for i in 1..n
    for j in 1..m
      delta = as[i] == bs[j] ? 0 : 2
      d[i][j] = [d[i-1][j] + 1, d[i][j-1] + 1, d[i-1][j-1] + delta].min
    end
  end
  return d[n][m]
end



   • 境界での初期化が必要になる
問題

• 挿入、削除に加えて置換を 1 score とカ
  ウントするように修正してみよ。

• 実際に書き換える方法を示せ
 • 最小手が複数ある場合は列挙せよ
一般に評価関数を書き換えたり出力を拡張するのは難しい
最長一致部分列(LCS)
• 入力:二つの文字列
• 出力:一致する部分列の最大長
 • 例:LCS(darling, airline) = 5 (“arlin”)
• 漸化式:d[i, j] = a , b までの LCS の長さ
                  i   j

 • 境界値:d[0, j] = d[i, 0] = 0
問題


• 実際に一致部分列を挙げよ
 • 複数ある場合は全て列挙してみよ
計算順序最適化
•   入力:括弧のついていない数式 A
•   出力:適切に括弧を付けて、答えを最大 /
    最小化せよ
    •   例: 1 + 2 × 3
    •   最大:(1+2) × 3 = 9 最小:1+(2×3)=7
•   数式のパーズ・ill-formed な部分列は排除し
    なくてはいけない
•   面倒なので、数字は一桁だけにする
漸化式
• a + b,a, b が最適値のとき。そこで
  ぞれ
        a × b が最適値を取るのは、それ

• d[i, j] = (i +1)文字∼ j 文字までの最適解


• 後はメモ化して書けばよいが、構文エ
  ラーなどの NULL の処理が入る
• 上の添字で合っているかぶっちゃけ不安
最長増加部分列(LIS)

• 与えられた数列の中で最も長い増加部
  分列の長さを求める。
• 入力:{3, 1, 4, 2, 5}
• 出力:3({3, 4, 5} と {1, 2, 5} が最長)
最長増加部分列
• d[i] = i 番目の要素が最後にくる増加列
  の長さ
• 候補:以下の内の長い方
 • a のみから成る列
   i

 • a 以前の a 未満の元の列に追加
   i    i
まとめ
•   DP = メモ化 + 部分最適化
    •   部分最適解から全体最適解が得られる時
        に使う
    •   指数空間の問題をほぼ多項式時間で解け
        る
•   添字の処理が面倒(バグの温床)
•   デバッグ・検証が難しい
•   細かな拡張性がわるい
ADP の紹介
動的計画法の問題点
•   行列に対する反復操作

    •   意味がわかりづらい

    •   添字がバグの温床

•   最適化・評価が渾然一体

    •   変更がしづらい

•   効率や正当性の検証がしづらい
ADP とは?
•   発想:解の生成と評価フェーズを分離

    •   最適化関数を再帰的に適用することで計
        算量を減らす

    •   コンパイラによる最適化等も活用

•   対象となる入力は「データ列」

    •   文字列に限らず、行列列、数列でもよい
解生成と評価の分離
•   DP を 文法 と 代数 に分割

    •   うわっ難しそう……;;

    •   名前がゴツいだけ!

    •   列をパーズして解の候補を生成、最適化
        しつつ評価、というのを形式的に書いた
ADP 作業の流れ

1. データ列の要素を決める

2. 扱う演算を決める

3. 評価関数を考える

4. 文法を書く
例:編集距離
•   文字の削除・挿入・置換の回数が最小に
    なるように文字列を書き換えたい

•   データ列の要素:文字

•   扱う演算の決定

    •   削除・挿入・置換を行った場所と、文字
        列の終端がわかればよい
評価代数の決定
•   評価代数とは:

    •   前で決めた演算に対応する評価関数

    •   解の候補から最適解を絞り込む最適化関数 h



                  標準的な「編集距離」
                  のスコア関数
評価代数の例2
   • 解の列挙や数え上げにも使える
    • 文法の定義の正当性を確認出来る!



列挙用代数。Nil などはコンストラクタ   数え上げ用代数
文法の定義(木)
•   入力:(“darling”, “airline”)

    •   一本にしたいので “darling$enilria” のように纏める
文法
•   木構造のパーズに使う文法:木文法

    •   能力的には CFG と同等

        •   導出規則に操作名のラベルを付けただけ
実際のコード:文法
alignmentGrammar :: AlignmentAlg Char ans -> String -> String -> [ans]
alignmentGrammar AlignmentAlg{..} inp1 inp2 =
     let inp = inp1 ++ '$': reverse inp2
         edit = tabulated $ -- 計算結果がメモ化可能であるということ
                    nil  <<< char '$'                     -- 終端;区切りは '$'
               ||| del   <<< anychar -~~ edit             -- 削除
               ||| ins   <<<             edit ~~- anychar -- 挿入
               ||| match <<< anychar -~~ edit ~~- anychar -- 置換
               ... h     -- 最適化函数がこれらの枝全てに適用可能
         z = mk inp
         (_, n) = bounds z
         char = char' z
         anychar = acharSep' z '$'
         tabulated = table n
     in axiom' n a




    •   ほぼ文法を ASCII に置き換えただけ

    •   評価関数・メモ化の有無を注釈できる
最適化関数 h と文法
• 解全体に h を適用すると指数時間
 • パーズしながら h が適用出来れば枝が
  刈れて、多項式時間で解ける!

• 「h を適用可能」を文法に注釈
コード:評価代数
-- | 編集距離の評価代数の型
data AlignmentAlg alph ans =
    AlignmentAlg { nil   :: alph -> ans                --   ^   終端
                 , del   :: alph -> ans -> ans         --   ^   削除
                 , ins   :: ans -> alph -> ans         --   ^   挿入
                 , match :: alph -> ans -> alph -> ans --   ^   置換
                 , h     :: [ans] -> [ans]             --   ^   最適化函数
                 }
-- | 列挙用のデータ型
data Edit = Nil
           | Del Char Edit
           | Ins Edit Char
           | Match Char Edit Char
             deriving (Eq, Ord, Show)

-- | 列挙用評価代数
enum :: AlignmentAlg Char Edit
enum = AlignmentAlg (const Nil) Del Ins Match id

-- | 数え上げ用評価代数
count :: AlignmentAlg Char Int
count = AlignmentAlg nil' del' ins' match' h'
  where
    nil' _ = 1; del' _ s = s; ins' s _ = s; match' _ s _ = s
    h' [] = []
    h' x = [sum x]
編集距離の代数
  -- | 編集距離計算用の評価代数
  unit :: AlignmentAlg Char Int
  unit = AlignmentAlg nil' del' ins' match' h'
    where
      nil' _ = 0              -- 終端のスコアはゼロ
      del' _ s = s + 1        -- 削除したら距離 + 1
      ins' s _ = s + 1        -- 挿入したら距離 + 1
      match' a s b
          | a == b    = s     -- 文字が一致したらそのまま
          | otherwise = s + 2 -- 一致しなければ + 2
      h' [] = []
      h' xs = [minimum xs]    -- 編集距離最小のものを選ぶ




• 列挙も評価も統一的に記述出来る!
試してみる
• 二つの代数の積 ⨂ を使うと、複数の条
 件を組み合わせることが出来る
ghci> alignmentGrammar count "darling" "airline"
[48639]

ghci> alignmentGrammar unit "darling" "airline"
[4]

ghci> alignmentGrammar (unit ⨂ pretty) "darling" "airline"
[(4,("da-rling-","-airlin-e")),(4,("da-rlin-g","-airline-")),
 (4,("da-rling","-airline"))]
例:最長一致部分列
• 実は、先程の文法を使って書ける
           •   文字が一致した時だけスコ
               アを +1

           •   最大値を持つものが欲しい

           •   重複ケースが出るので、枝
               刈りするには文法を改善
例:計算順序最適化
 •   今度は複数桁に対応してみる

 •   必要な演算は加算、乗算、数値、数値の拡張

data Bill =   Add Bill   Char Bill  -- ^   加算
          |   Mul Bill   Char Bill  -- ^   乗算
          |   Ext Bill   Char       -- ^   数字の桁の続き "123" の 3 の部分
          |   Val Char              -- ^   数字
              deriving   (Show, Eq, Ord)

data BillAlg alph   ans =
    BillAlg { add   :: ans -> alph -> ans -> ans
            , mul   :: ans -> alph -> ans -> ans
            , ext   :: ans -> alph -> ans
            , val   :: alph -> ans
            , h     :: [ans] -> [ans]
            }
代数
   -- | 数式を pretty print する代数
   pretty :: BillAlg Char String
   pretty = BillAlg add' mul' ext' val' h'
     where
       add' x _ y = "(" ++ x ++ " + " ++ y ++ ")"
       mul' x _ y = "(" ++ x ++ " * " ++ y ++ ")"
       val' c = [c]
       ext' i c = i ++ [c]
       h' = id

   -- | 最小化代数
   billMin :: BillAlg Char Int
   billMin = BillAlg add' mul' ext' val' h'
     where
       add' x _ y = x + y
       mul' x _ y = x * y
       val' c     = digitToInt c
       ext' i c   = i * 10 + digitToInt c
       h' [] = []
       h' xs = [minimum xs]




• 列挙・数え上げ・最大化も同様
文法
    billGrammar :: BillAlg Char ans -> String -> [ans]
    billGrammar BillAlg{..} inp = axiom' n bill
      where
        bill = tabulated $          -- 結果をメモ化する
               number
           ||| (add <<< bill ~~- char '+') ~~~ bill
               -- 右側のパーズ結果が一定の文字数を越えないとき ~~- を使う
               -- 結合的でないので括弧がついている
           ||| (mul <<< bill ~~- char '*') ~~~ bill
           ... h     -- 数式それ自体には最適化函数を逐次適用
        number = val <<< digit
             ||| ext <<< number ~~- digit
                 -- 数値のパーズに h をつけてもしょうがない
                 -- メモ化する意味も余りない




•   メモ化・最適化関数の適用を陽に指定できる強み

•   文法を定義するのでパーズと解生成を一気にできる
例:最長増加部分列
•   解の生成で増加列を直に生成出来ればいいが…

•   木文法は CFG とほぼ同等。「増加列」の概念
    は木のラベル込みだと文脈依存になる(ハズ)

•   全ての部分文字列を生成して、評価関数でフィ
    ルターするより他にない

    •   ADP には向かない例(省略)
まとめ:ADP
• データ列に対する DP の抽象化
• 解の生成と評価・最適化を分離
 • モジュラリティが高い
 • 似た問題をほぼ同じ枠組で解ける
• 添字が出て来ない(バグ温床の解消)
• 文法のデザインが一番難しい
• CFG で表現出来ない物は余り向かない
時間計算量?
• 書き易さや検証可能性はよい。計算量は?
• 仮定:最適化関数 h の返す値の数は有界(1
  個とか n 個以下とか)
• count 代数や最適化関数は一つなので良い
• n-best 解も n で抑えられるのでよい
• 列挙代数は爆発するので駄目
• 文法から計算量の見積りが出来る
計算量の見積り


•   weight(G) : 文法に現れる木の中でサイズが抑えられない非
    終端記号(非有界ノードと呼ぶ)の数の最大値 - 1

•   このとき、時間計算量 O(n2+width(G)) となる

•   計算量の見積りも簡単

•   計算量を減らすには文法の非終端記号を分割して工夫する
見積りの例
• 編集距離:非有界ノードは edit のみ。
 どの木にも一つずつしか出現しないの
 で width(G) = 0。計算量はO(n2)

• 計算順序:非有界ノードは bill と
 number。bill は add や mul に二回登場。
 width(G) = 1。計算量はO(n3)
発展
•   ADP は生のチューンされた DP よりは速くな
    かったりする

    •   Stream Fusion の技術と組み合わせて C のと
        定数倍くらいの差まで迫れる

•   複数入力を一つに纏める必要がある

    •   MCFG(Multiple CFG)を使って複数入力に対
        応したバージョンもある
MCFGの例:編集距離
rewriteDel [c, a1, a2] = ([c, a1], [a2])
rewriteIns [c, a1, a2] = ([a1], [c, a2])
rewriteMatch [c1,c2,a1,a2] = ([c1, a1], [c2, a2])
edit = tabulated2 $
         nil   <<< (EPS, EPS)                     >>>|| id2
     ||| del   <<< anychar ~~~|| edit             >>>|| rewriteDel
     ||| ins   <<< anychar ~~~|| edit             >>>|| rewriteIns
     ||| match <<< anychar ~~~ anychar ~~~|| edit >>>|| rewriteMatch
     ... h




• 複数入力をどう変形するかルールを書く
• 細かい解説は省略。
参考文献
•   “The Algebraic Dynamic Programming Homepage”, ADP project
    team, 2009
•   “adp-multi”, Maik Riechert, 2012
•   “A Discipline of Dynamic Programming over Sequence Data”, Robert
    Giegerich, Carsten Meyer and Peter Steffen, 2004
•   “Sneaking Around concatMap - Efficient Combinators for Dynamic
    Programming”, Christian Honer zu Siederdissen, 2012
•   “Algebraic Dynamic Programming”, R. Giegerich and C. Meyer, 2002
•   “プログラミングコンテストチャレンジブック”, 秋葉拓哉, 岩田
    陽一 and 北側宜稔, 毎日コミュニケーションズ, 2010

•   “動的計画法 - Wikipedia”, Wikipedia, 2012
Any Questions?
御清聴
ありがとうございました

Mais conteúdo relacionado

Mais procurados

Rolling Hashを殺す話
Rolling Hashを殺す話Rolling Hashを殺す話
Rolling Hashを殺す話Nagisa Eto
 
Freer Monads, More Extensible Effects
Freer Monads, More Extensible EffectsFreer Monads, More Extensible Effects
Freer Monads, More Extensible EffectsHiromi Ishii
 
プログラミングコンテストでのデータ構造
プログラミングコンテストでのデータ構造プログラミングコンテストでのデータ構造
プログラミングコンテストでのデータ構造Takuya Akiba
 
Union find(素集合データ構造)
Union find(素集合データ構造)Union find(素集合データ構造)
Union find(素集合データ構造)AtCoder Inc.
 
第21回アルゴリズム勉強会
第21回アルゴリズム勉強会第21回アルゴリズム勉強会
第21回アルゴリズム勉強会Yuuki Ono
 
色々なダイクストラ高速化
色々なダイクストラ高速化色々なダイクストラ高速化
色々なダイクストラ高速化yosupo
 
二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方
二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方
二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方Kensuke Otsuki
 
C++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプC++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプKohsuke Yuasa
 
プログラミングコンテストでの動的計画法
プログラミングコンテストでの動的計画法プログラミングコンテストでの動的計画法
プログラミングコンテストでの動的計画法Takuya Akiba
 
勉強か?趣味か?人生か?―プログラミングコンテストとは
勉強か?趣味か?人生か?―プログラミングコンテストとは勉強か?趣味か?人生か?―プログラミングコンテストとは
勉強か?趣味か?人生か?―プログラミングコンテストとはTakuya Akiba
 
ユークリッド最小全域木
ユークリッド最小全域木ユークリッド最小全域木
ユークリッド最小全域木理玖 川崎
 
五次方程式はやっぱり解ける #日曜数学会
五次方程式はやっぱり解ける #日曜数学会五次方程式はやっぱり解ける #日曜数学会
五次方程式はやっぱり解ける #日曜数学会Junpei Tsuji
 
Re永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライドRe永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライドMasaki Hara
 
高速フーリエ変換
高速フーリエ変換高速フーリエ変換
高速フーリエ変換AtCoder Inc.
 
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)Hiro H.
 
C++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISるC++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISるHideyuki Tanaka
 

Mais procurados (20)

Rolling Hashを殺す話
Rolling Hashを殺す話Rolling Hashを殺す話
Rolling Hashを殺す話
 
Freer Monads, More Extensible Effects
Freer Monads, More Extensible EffectsFreer Monads, More Extensible Effects
Freer Monads, More Extensible Effects
 
プログラミングコンテストでのデータ構造
プログラミングコンテストでのデータ構造プログラミングコンテストでのデータ構造
プログラミングコンテストでのデータ構造
 
Union find(素集合データ構造)
Union find(素集合データ構造)Union find(素集合データ構造)
Union find(素集合データ構造)
 
第21回アルゴリズム勉強会
第21回アルゴリズム勉強会第21回アルゴリズム勉強会
第21回アルゴリズム勉強会
 
色々なダイクストラ高速化
色々なダイクストラ高速化色々なダイクストラ高速化
色々なダイクストラ高速化
 
二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方
二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方
二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方
 
文字列アルゴリズム
文字列アルゴリズム文字列アルゴリズム
文字列アルゴリズム
 
C++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプC++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプ
 
プログラミングコンテストでの動的計画法
プログラミングコンテストでの動的計画法プログラミングコンテストでの動的計画法
プログラミングコンテストでの動的計画法
 
勉強か?趣味か?人生か?―プログラミングコンテストとは
勉強か?趣味か?人生か?―プログラミングコンテストとは勉強か?趣味か?人生か?―プログラミングコンテストとは
勉強か?趣味か?人生か?―プログラミングコンテストとは
 
ユークリッド最小全域木
ユークリッド最小全域木ユークリッド最小全域木
ユークリッド最小全域木
 
動的計画法を極める!
動的計画法を極める!動的計画法を極める!
動的計画法を極める!
 
五次方程式はやっぱり解ける #日曜数学会
五次方程式はやっぱり解ける #日曜数学会五次方程式はやっぱり解ける #日曜数学会
五次方程式はやっぱり解ける #日曜数学会
 
Re永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライドRe永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライド
 
高速フーリエ変換
高速フーリエ変換高速フーリエ変換
高速フーリエ変換
 
Rolling hash
Rolling hashRolling hash
Rolling hash
 
グラフと木
グラフと木グラフと木
グラフと木
 
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
 
C++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISるC++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISる
 

Semelhante a Algebraic DP: 動的計画法を書きやすく

2011年11月11日
2011年11月11日2011年11月11日
2011年11月11日nukaemon
 
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
 
第15回 配信講義 計算科学技術特論B(2022)
第15回 配信講義 計算科学技術特論B(2022)第15回 配信講義 計算科学技術特論B(2022)
第15回 配信講義 計算科学技術特論B(2022)RCCSRENKEI
 
JavaScriptクイックスタート
JavaScriptクイックスタートJavaScriptクイックスタート
JavaScriptクイックスタートShumpei Shiraishi
 
6_C言語入門 - 式と演算子について
6_C言語入門 - 式と演算子について6_C言語入門 - 式と演算子について
6_C言語入門 - 式と演算子についてbc_rikko
 
C++11概要 ライブラリ編
C++11概要 ライブラリ編C++11概要 ライブラリ編
C++11概要 ライブラリ編egtra
 
AtCoder Regular Contest 030 解説
AtCoder Regular Contest 030 解説AtCoder Regular Contest 030 解説
AtCoder Regular Contest 030 解説AtCoder Inc.
 
あなたのScalaを爆速にする7つの方法(日本語版)
あなたのScalaを爆速にする7つの方法(日本語版)あなたのScalaを爆速にする7つの方法(日本語版)
あなたのScalaを爆速にする7つの方法(日本語版)x1 ichi
 
関数プログラミング入門
関数プログラミング入門関数プログラミング入門
関数プログラミング入門Hideyuki Tanaka
 
超初心者がローマ数字をいろいろパースしてみる
超初心者がローマ数字をいろいろパースしてみる超初心者がローマ数字をいろいろパースしてみる
超初心者がローマ数字をいろいろパースしてみるいずみ よねざわ
 
Introduction to NumPy & SciPy
Introduction to NumPy & SciPyIntroduction to NumPy & SciPy
Introduction to NumPy & SciPyShiqiao Du
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料時響 逢坂
 
Boost jp9 program_options
Boost jp9 program_optionsBoost jp9 program_options
Boost jp9 program_optionsnyaocat
 
(Lambdaだけで) 純LISPのような ナニかを作る
(Lambdaだけで)純LISPのようなナニかを作る(Lambdaだけで)純LISPのようなナニかを作る
(Lambdaだけで) 純LISPのような ナニかを作るDaichi Teruya
 
Ruby 3の型推論やってます
Ruby 3の型推論やってますRuby 3の型推論やってます
Ruby 3の型推論やってますmametter
 

Semelhante a Algebraic DP: 動的計画法を書きやすく (20)

2011年11月11日
2011年11月11日2011年11月11日
2011年11月11日
 
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
 
第15回 配信講義 計算科学技術特論B(2022)
第15回 配信講義 計算科学技術特論B(2022)第15回 配信講義 計算科学技術特論B(2022)
第15回 配信講義 計算科学技術特論B(2022)
 
JavaScriptクイックスタート
JavaScriptクイックスタートJavaScriptクイックスタート
JavaScriptクイックスタート
 
6_C言語入門 - 式と演算子について
6_C言語入門 - 式と演算子について6_C言語入門 - 式と演算子について
6_C言語入門 - 式と演算子について
 
C++11概要 ライブラリ編
C++11概要 ライブラリ編C++11概要 ライブラリ編
C++11概要 ライブラリ編
 
AtCoder Regular Contest 030 解説
AtCoder Regular Contest 030 解説AtCoder Regular Contest 030 解説
AtCoder Regular Contest 030 解説
 
Python opt
Python optPython opt
Python opt
 
20180728 halide-study
20180728 halide-study20180728 halide-study
20180728 halide-study
 
あなたのScalaを爆速にする7つの方法(日本語版)
あなたのScalaを爆速にする7つの方法(日本語版)あなたのScalaを爆速にする7つの方法(日本語版)
あなたのScalaを爆速にする7つの方法(日本語版)
 
Pythonintro
PythonintroPythonintro
Pythonintro
 
関数プログラミング入門
関数プログラミング入門関数プログラミング入門
関数プログラミング入門
 
超初心者がローマ数字をいろいろパースしてみる
超初心者がローマ数字をいろいろパースしてみる超初心者がローマ数字をいろいろパースしてみる
超初心者がローマ数字をいろいろパースしてみる
 
Introduction to NumPy & SciPy
Introduction to NumPy & SciPyIntroduction to NumPy & SciPy
Introduction to NumPy & SciPy
 
C言語講習会3
C言語講習会3C言語講習会3
C言語講習会3
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料
 
Boost jp9 program_options
Boost jp9 program_optionsBoost jp9 program_options
Boost jp9 program_options
 
Lisp講義1
Lisp講義1Lisp講義1
Lisp講義1
 
(Lambdaだけで) 純LISPのような ナニかを作る
(Lambdaだけで)純LISPのようなナニかを作る(Lambdaだけで)純LISPのようなナニかを作る
(Lambdaだけで) 純LISPのような ナニかを作る
 
Ruby 3の型推論やってます
Ruby 3の型推論やってますRuby 3の型推論やってます
Ruby 3の型推論やってます
 

Mais de Hiromi Ishii

ものまね鳥を愛でる 結合子論理と計算
ものまね鳥を愛でる 結合子論理と計算ものまね鳥を愛でる 結合子論理と計算
ものまね鳥を愛でる 結合子論理と計算Hiromi Ishii
 
Lebesgue可測性に関するSoloayの定理と実数の集合の正則性
Lebesgue可測性に関するSoloayの定理と実数の集合の正則性Lebesgue可測性に関するSoloayの定理と実数の集合の正則性
Lebesgue可測性に関するSoloayの定理と実数の集合の正則性Hiromi Ishii
 
実数の集合はどこまで可測になれるか?
実数の集合はどこまで可測になれるか?実数の集合はどこまで可測になれるか?
実数の集合はどこまで可測になれるか?Hiromi Ishii
 
(数式の入った)本をつくる
(数式の入った)本をつくる(数式の入った)本をつくる
(数式の入った)本をつくるHiromi Ishii
 
御清聴ありがとうございました
御清聴ありがとうございました御清聴ありがとうございました
御清聴ありがとうございましたHiromi Ishii
 
Lebesgue 可測性に関する Solovay-Shelah の結果に必要な記述集合論のごく基本的な事項
Lebesgue 可測性に関する Solovay-Shelah の結果に必要な記述集合論のごく基本的な事項Lebesgue 可測性に関する Solovay-Shelah の結果に必要な記述集合論のごく基本的な事項
Lebesgue 可測性に関する Solovay-Shelah の結果に必要な記述集合論のごく基本的な事項Hiromi Ishii
 
技術者が知るべき Gröbner 基底
技術者が知るべき Gröbner 基底技術者が知るべき Gröbner 基底
技術者が知るべき Gröbner 基底Hiromi Ishii
 
数学プログラムを Haskell で書くべき 6 の理由
数学プログラムを Haskell で書くべき 6 の理由数学プログラムを Haskell で書くべき 6 の理由
数学プログラムを Haskell で書くべき 6 の理由Hiromi Ishii
 
Yesod でブログエンジンをつくってみた
Yesod でブログエンジンをつくってみたYesod でブログエンジンをつくってみた
Yesod でブログエンジンをつくってみたHiromi Ishii
 
Yesodを支える技術
Yesodを支える技術Yesodを支える技術
Yesodを支える技術Hiromi Ishii
 
Alloy Analyzer のこと
Alloy Analyzer のことAlloy Analyzer のこと
Alloy Analyzer のことHiromi Ishii
 
Invertible-syntax 入門
Invertible-syntax 入門Invertible-syntax 入門
Invertible-syntax 入門Hiromi Ishii
 
Metaprogramming in Haskell
Metaprogramming in HaskellMetaprogramming in Haskell
Metaprogramming in HaskellHiromi Ishii
 
Template Haskell とか
Template Haskell とかTemplate Haskell とか
Template Haskell とかHiromi Ishii
 
実践・完全犯罪のつくり方
実践・完全犯罪のつくり方実践・完全犯罪のつくり方
実践・完全犯罪のつくり方Hiromi Ishii
 

Mais de Hiromi Ishii (16)

ものまね鳥を愛でる 結合子論理と計算
ものまね鳥を愛でる 結合子論理と計算ものまね鳥を愛でる 結合子論理と計算
ものまね鳥を愛でる 結合子論理と計算
 
Lebesgue可測性に関するSoloayの定理と実数の集合の正則性
Lebesgue可測性に関するSoloayの定理と実数の集合の正則性Lebesgue可測性に関するSoloayの定理と実数の集合の正則性
Lebesgue可測性に関するSoloayの定理と実数の集合の正則性
 
実数の集合はどこまで可測になれるか?
実数の集合はどこまで可測になれるか?実数の集合はどこまで可測になれるか?
実数の集合はどこまで可測になれるか?
 
(数式の入った)本をつくる
(数式の入った)本をつくる(数式の入った)本をつくる
(数式の入った)本をつくる
 
御清聴ありがとうございました
御清聴ありがとうございました御清聴ありがとうございました
御清聴ありがとうございました
 
Lebesgue 可測性に関する Solovay-Shelah の結果に必要な記述集合論のごく基本的な事項
Lebesgue 可測性に関する Solovay-Shelah の結果に必要な記述集合論のごく基本的な事項Lebesgue 可測性に関する Solovay-Shelah の結果に必要な記述集合論のごく基本的な事項
Lebesgue 可測性に関する Solovay-Shelah の結果に必要な記述集合論のごく基本的な事項
 
技術者が知るべき Gröbner 基底
技術者が知るべき Gröbner 基底技術者が知るべき Gröbner 基底
技術者が知るべき Gröbner 基底
 
数学プログラムを Haskell で書くべき 6 の理由
数学プログラムを Haskell で書くべき 6 の理由数学プログラムを Haskell で書くべき 6 の理由
数学プログラムを Haskell で書くべき 6 の理由
 
Yesod でブログエンジンをつくってみた
Yesod でブログエンジンをつくってみたYesod でブログエンジンをつくってみた
Yesod でブログエンジンをつくってみた
 
Yesodを支える技術
Yesodを支える技術Yesodを支える技術
Yesodを支える技術
 
Alloy Analyzer のこと
Alloy Analyzer のことAlloy Analyzer のこと
Alloy Analyzer のこと
 
Invertible-syntax 入門
Invertible-syntax 入門Invertible-syntax 入門
Invertible-syntax 入門
 
最終発表
最終発表最終発表
最終発表
 
Metaprogramming in Haskell
Metaprogramming in HaskellMetaprogramming in Haskell
Metaprogramming in Haskell
 
Template Haskell とか
Template Haskell とかTemplate Haskell とか
Template Haskell とか
 
実践・完全犯罪のつくり方
実践・完全犯罪のつくり方実践・完全犯罪のつくり方
実践・完全犯罪のつくり方
 

Último

新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsWSO2
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptxsn679259
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video UnderstandingToru Tamaki
 
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Gamesatsushi061452
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイスCRI Japan, Inc.
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルCRI Japan, Inc.
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...Toru Tamaki
 

Último (10)

新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native Integrations
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
 
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
 

Algebraic DP: 動的計画法を書きやすく

  • 2. 自己紹介 • 石井 大海 (id:mr_konn / @mr_konn) • 早稲田大学数学科三年 • 集合論やモデル理論、圏論、代数学に興味 • 函数型言語、定理証明系など形式手法にも興味 • 2010 Summer Intern から PFI でバイト中 • Haskell で Twitter やWebのクローラを書いている
  • 3. 今日のおはなし • 朗報:Haskell の話じゃありません! • が、Haskell を使います。 • Algebraic Dynamic Programming (ADP) • 連続データに対する動的計画法の新しい 設計・実装法 • バイオインフォマティクスの分野から
  • 4. Table of Contents • 動的計画法の復習 • 動的計画法とは? • 動的計画法の例 • ADP の紹介 • 動的計画法の問題点 • ADP とは?──原理と例 • ADP の改良版 • まとめ
  • 8. 結局どういうこと? • 小さい範囲の最適解を組み合わせて解ける最適 化問題を • 小さい部分での結果をメモ化しながら解く方法 • 指数時間かかりそうなものがだいたい多項式 時間で解けるようになる • 部分問題と全体の漸化式で表わされ、アルゴリズ ムはメモ化行列への反復作業として記述される
  • 9. 動的計画法の例 • 編集距離 • 最長一致部分列 • 括弧の位置最適化 • 最長増加部分列
  • 10. 編集距離 • 入力:二つの文字列 • 出力:一方の文字列に文字を挿入・削除す ることで他方の文字列にするのに必要な最 短手数 • 例:(darling, airline) • 4(darling→arling→airling→airlin→airline)
  • 11. 編集距離の考え方 • 入力:(a1a2...an, b1b2...bm) • d[i, j] = a1...ai と b1...bj の編集距離 • d[i+1, j+1] の候補: • ai+1 までを bj に編集して、bj+1を足す • ai までを bj+1 に編集して、ai+1 を削る • ai までを bj に編集して、ai+1を削ってbj+1を足す • これらの中で最も手数が少ないもの
  • 12. 編集距離の漸化式 • これをメモ化して、i, j を 1 から埋めて 再帰していく
  • 13. 実装例(Ruby) def edit_distance(as, bs) n = as.length m = bs.length d = Hash.new {|h, k| h[k] = Hash.new(0)} for i in 0..n d[i][0] = i end for j in 0..m d[0][j] = j end for i in 1..n for j in 1..m delta = as[i] == bs[j] ? 0 : 2 d[i][j] = [d[i-1][j] + 1, d[i][j-1] + 1, d[i-1][j-1] + delta].min end end return d[n][m] end • 境界での初期化が必要になる
  • 14. 問題 • 挿入、削除に加えて置換を 1 score とカ ウントするように修正してみよ。 • 実際に書き換える方法を示せ • 最小手が複数ある場合は列挙せよ 一般に評価関数を書き換えたり出力を拡張するのは難しい
  • 15. 最長一致部分列(LCS) • 入力:二つの文字列 • 出力:一致する部分列の最大長 • 例:LCS(darling, airline) = 5 (“arlin”) • 漸化式:d[i, j] = a , b までの LCS の長さ i j • 境界値:d[0, j] = d[i, 0] = 0
  • 16. 問題 • 実際に一致部分列を挙げよ • 複数ある場合は全て列挙してみよ
  • 17. 計算順序最適化 • 入力:括弧のついていない数式 A • 出力:適切に括弧を付けて、答えを最大 / 最小化せよ • 例: 1 + 2 × 3 • 最大:(1+2) × 3 = 9 最小:1+(2×3)=7 • 数式のパーズ・ill-formed な部分列は排除し なくてはいけない • 面倒なので、数字は一桁だけにする
  • 18. 漸化式 • a + b,a, b が最適値のとき。そこで ぞれ a × b が最適値を取るのは、それ • d[i, j] = (i +1)文字∼ j 文字までの最適解 • 後はメモ化して書けばよいが、構文エ ラーなどの NULL の処理が入る • 上の添字で合っているかぶっちゃけ不安
  • 19. 最長増加部分列(LIS) • 与えられた数列の中で最も長い増加部 分列の長さを求める。 • 入力:{3, 1, 4, 2, 5} • 出力:3({3, 4, 5} と {1, 2, 5} が最長)
  • 20. 最長増加部分列 • d[i] = i 番目の要素が最後にくる増加列 の長さ • 候補:以下の内の長い方 • a のみから成る列 i • a 以前の a 未満の元の列に追加 i i
  • 21. まとめ • DP = メモ化 + 部分最適化 • 部分最適解から全体最適解が得られる時 に使う • 指数空間の問題をほぼ多項式時間で解け る • 添字の処理が面倒(バグの温床) • デバッグ・検証が難しい • 細かな拡張性がわるい
  • 23. 動的計画法の問題点 • 行列に対する反復操作 • 意味がわかりづらい • 添字がバグの温床 • 最適化・評価が渾然一体 • 変更がしづらい • 効率や正当性の検証がしづらい
  • 24. ADP とは? • 発想:解の生成と評価フェーズを分離 • 最適化関数を再帰的に適用することで計 算量を減らす • コンパイラによる最適化等も活用 • 対象となる入力は「データ列」 • 文字列に限らず、行列列、数列でもよい
  • 25. 解生成と評価の分離 • DP を 文法 と 代数 に分割 • うわっ難しそう……;; • 名前がゴツいだけ! • 列をパーズして解の候補を生成、最適化 しつつ評価、というのを形式的に書いた
  • 26. ADP 作業の流れ 1. データ列の要素を決める 2. 扱う演算を決める 3. 評価関数を考える 4. 文法を書く
  • 27. 例:編集距離 • 文字の削除・挿入・置換の回数が最小に なるように文字列を書き換えたい • データ列の要素:文字 • 扱う演算の決定 • 削除・挿入・置換を行った場所と、文字 列の終端がわかればよい
  • 28. 評価代数の決定 • 評価代数とは: • 前で決めた演算に対応する評価関数 • 解の候補から最適解を絞り込む最適化関数 h 標準的な「編集距離」 のスコア関数
  • 29. 評価代数の例2 • 解の列挙や数え上げにも使える • 文法の定義の正当性を確認出来る! 列挙用代数。Nil などはコンストラクタ 数え上げ用代数
  • 30. 文法の定義(木) • 入力:(“darling”, “airline”) • 一本にしたいので “darling$enilria” のように纏める
  • 31. 文法 • 木構造のパーズに使う文法:木文法 • 能力的には CFG と同等 • 導出規則に操作名のラベルを付けただけ
  • 32. 実際のコード:文法 alignmentGrammar :: AlignmentAlg Char ans -> String -> String -> [ans] alignmentGrammar AlignmentAlg{..} inp1 inp2 = let inp = inp1 ++ '$': reverse inp2 edit = tabulated $ -- 計算結果がメモ化可能であるということ nil <<< char '$' -- 終端;区切りは '$' ||| del <<< anychar -~~ edit -- 削除 ||| ins <<< edit ~~- anychar -- 挿入 ||| match <<< anychar -~~ edit ~~- anychar -- 置換 ... h -- 最適化函数がこれらの枝全てに適用可能 z = mk inp (_, n) = bounds z char = char' z anychar = acharSep' z '$' tabulated = table n in axiom' n a • ほぼ文法を ASCII に置き換えただけ • 評価関数・メモ化の有無を注釈できる
  • 33. 最適化関数 h と文法 • 解全体に h を適用すると指数時間 • パーズしながら h が適用出来れば枝が 刈れて、多項式時間で解ける! • 「h を適用可能」を文法に注釈
  • 34. コード:評価代数 -- | 編集距離の評価代数の型 data AlignmentAlg alph ans = AlignmentAlg { nil :: alph -> ans -- ^ 終端 , del :: alph -> ans -> ans -- ^ 削除 , ins :: ans -> alph -> ans -- ^ 挿入 , match :: alph -> ans -> alph -> ans -- ^ 置換 , h :: [ans] -> [ans] -- ^ 最適化函数 } -- | 列挙用のデータ型 data Edit = Nil | Del Char Edit | Ins Edit Char | Match Char Edit Char deriving (Eq, Ord, Show) -- | 列挙用評価代数 enum :: AlignmentAlg Char Edit enum = AlignmentAlg (const Nil) Del Ins Match id -- | 数え上げ用評価代数 count :: AlignmentAlg Char Int count = AlignmentAlg nil' del' ins' match' h' where nil' _ = 1; del' _ s = s; ins' s _ = s; match' _ s _ = s h' [] = [] h' x = [sum x]
  • 35. 編集距離の代数 -- | 編集距離計算用の評価代数 unit :: AlignmentAlg Char Int unit = AlignmentAlg nil' del' ins' match' h' where nil' _ = 0 -- 終端のスコアはゼロ del' _ s = s + 1 -- 削除したら距離 + 1 ins' s _ = s + 1 -- 挿入したら距離 + 1 match' a s b | a == b = s -- 文字が一致したらそのまま | otherwise = s + 2 -- 一致しなければ + 2 h' [] = [] h' xs = [minimum xs] -- 編集距離最小のものを選ぶ • 列挙も評価も統一的に記述出来る!
  • 36. 試してみる • 二つの代数の積 ⨂ を使うと、複数の条 件を組み合わせることが出来る ghci> alignmentGrammar count "darling" "airline" [48639] ghci> alignmentGrammar unit "darling" "airline" [4] ghci> alignmentGrammar (unit ⨂ pretty) "darling" "airline" [(4,("da-rling-","-airlin-e")),(4,("da-rlin-g","-airline-")), (4,("da-rling","-airline"))]
  • 37. 例:最長一致部分列 • 実は、先程の文法を使って書ける • 文字が一致した時だけスコ アを +1 • 最大値を持つものが欲しい • 重複ケースが出るので、枝 刈りするには文法を改善
  • 38. 例:計算順序最適化 • 今度は複数桁に対応してみる • 必要な演算は加算、乗算、数値、数値の拡張 data Bill = Add Bill Char Bill -- ^ 加算 | Mul Bill Char Bill -- ^ 乗算 | Ext Bill Char -- ^ 数字の桁の続き "123" の 3 の部分 | Val Char -- ^ 数字 deriving (Show, Eq, Ord) data BillAlg alph ans = BillAlg { add :: ans -> alph -> ans -> ans , mul :: ans -> alph -> ans -> ans , ext :: ans -> alph -> ans , val :: alph -> ans , h :: [ans] -> [ans] }
  • 39. 代数 -- | 数式を pretty print する代数 pretty :: BillAlg Char String pretty = BillAlg add' mul' ext' val' h' where add' x _ y = "(" ++ x ++ " + " ++ y ++ ")" mul' x _ y = "(" ++ x ++ " * " ++ y ++ ")" val' c = [c] ext' i c = i ++ [c] h' = id -- | 最小化代数 billMin :: BillAlg Char Int billMin = BillAlg add' mul' ext' val' h' where add' x _ y = x + y mul' x _ y = x * y val' c = digitToInt c ext' i c = i * 10 + digitToInt c h' [] = [] h' xs = [minimum xs] • 列挙・数え上げ・最大化も同様
  • 40. 文法 billGrammar :: BillAlg Char ans -> String -> [ans] billGrammar BillAlg{..} inp = axiom' n bill where bill = tabulated $ -- 結果をメモ化する number ||| (add <<< bill ~~- char '+') ~~~ bill -- 右側のパーズ結果が一定の文字数を越えないとき ~~- を使う -- 結合的でないので括弧がついている ||| (mul <<< bill ~~- char '*') ~~~ bill ... h -- 数式それ自体には最適化函数を逐次適用 number = val <<< digit ||| ext <<< number ~~- digit -- 数値のパーズに h をつけてもしょうがない -- メモ化する意味も余りない • メモ化・最適化関数の適用を陽に指定できる強み • 文法を定義するのでパーズと解生成を一気にできる
  • 41. 例:最長増加部分列 • 解の生成で増加列を直に生成出来ればいいが… • 木文法は CFG とほぼ同等。「増加列」の概念 は木のラベル込みだと文脈依存になる(ハズ) • 全ての部分文字列を生成して、評価関数でフィ ルターするより他にない • ADP には向かない例(省略)
  • 42. まとめ:ADP • データ列に対する DP の抽象化 • 解の生成と評価・最適化を分離 • モジュラリティが高い • 似た問題をほぼ同じ枠組で解ける • 添字が出て来ない(バグ温床の解消) • 文法のデザインが一番難しい • CFG で表現出来ない物は余り向かない
  • 43. 時間計算量? • 書き易さや検証可能性はよい。計算量は? • 仮定:最適化関数 h の返す値の数は有界(1 個とか n 個以下とか) • count 代数や最適化関数は一つなので良い • n-best 解も n で抑えられるのでよい • 列挙代数は爆発するので駄目 • 文法から計算量の見積りが出来る
  • 44. 計算量の見積り • weight(G) : 文法に現れる木の中でサイズが抑えられない非 終端記号(非有界ノードと呼ぶ)の数の最大値 - 1 • このとき、時間計算量 O(n2+width(G)) となる • 計算量の見積りも簡単 • 計算量を減らすには文法の非終端記号を分割して工夫する
  • 45. 見積りの例 • 編集距離:非有界ノードは edit のみ。 どの木にも一つずつしか出現しないの で width(G) = 0。計算量はO(n2) • 計算順序:非有界ノードは bill と number。bill は add や mul に二回登場。 width(G) = 1。計算量はO(n3)
  • 46. 発展 • ADP は生のチューンされた DP よりは速くな かったりする • Stream Fusion の技術と組み合わせて C のと 定数倍くらいの差まで迫れる • 複数入力を一つに纏める必要がある • MCFG(Multiple CFG)を使って複数入力に対 応したバージョンもある
  • 47. MCFGの例:編集距離 rewriteDel [c, a1, a2] = ([c, a1], [a2]) rewriteIns [c, a1, a2] = ([a1], [c, a2]) rewriteMatch [c1,c2,a1,a2] = ([c1, a1], [c2, a2]) edit = tabulated2 $ nil <<< (EPS, EPS) >>>|| id2 ||| del <<< anychar ~~~|| edit >>>|| rewriteDel ||| ins <<< anychar ~~~|| edit >>>|| rewriteIns ||| match <<< anychar ~~~ anychar ~~~|| edit >>>|| rewriteMatch ... h • 複数入力をどう変形するかルールを書く • 細かい解説は省略。
  • 48. 参考文献 • “The Algebraic Dynamic Programming Homepage”, ADP project team, 2009 • “adp-multi”, Maik Riechert, 2012 • “A Discipline of Dynamic Programming over Sequence Data”, Robert Giegerich, Carsten Meyer and Peter Steffen, 2004 • “Sneaking Around concatMap - Efficient Combinators for Dynamic Programming”, Christian Honer zu Siederdissen, 2012 • “Algebraic Dynamic Programming”, R. Giegerich and C. Meyer, 2002 • “プログラミングコンテストチャレンジブック”, 秋葉拓哉, 岩田 陽一 and 北側宜稔, 毎日コミュニケーションズ, 2010 • “動的計画法 - Wikipedia”, Wikipedia, 2012

Notas do Editor

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n