ia16

36
Introduction to Algorithms Chapter 16 Greedy Algorithm

Upload: mfumi

Post on 11-Apr-2017

483 views

Category:

Technology


0 download

TRANSCRIPT

Introduction to Algorithms Chapter 16

Greedy Algorithm

貪欲法

• 多くの最適化問題でDPはoverkill=> 貪欲法

• 貪欲法ではある時点で最も良いものを選んでいく

• 必ず最適解が得られる訳ではないが,うまく行く事も多い

16.1 An activity-selection problem

• n個のactivityの集合 S = {a1,a2,…,an}

• 各aiは開始時刻siと終了時刻fiが決まっている

• 決められた時間の中で各activityが重ならないという条件のもとで最も多くのactivityが実行できるようなSの部分集合を求めたい

問題例

• 例えば{a3, a9, a11} はそれぞれ重なることがない

• {a1, a4, a8, a11} もしくは {a2, a4, a9, a11} が重ならないでかつactivityの数が最大となる集合

問題の分解• Sij を ai が終了し,ajが始まるまでのactivityの集合とする

• お互い重ならないでactivity数が最大のSijの部分集合を求めたい.そのような集合をAijとする

• あるactivity ak がAijに含まれるとする.すると,残りは1. Sik(aiより後,akより前に終わるactivityの集合)と,2. Skj(akより後,ajより前に終わるactivityの集合) の集合の中で最も良い部分集合を求める問題になる

問題の分解

• Aik = Aij ∩ SikAkj = Aij ∩ Skj => Aij = Aik ∪ {ak} ∪ Akj |Aij| = |Aik| + |Akj| + 1

DPによる解法

• Sijの最適な部分集合の数を c[i,j] とすると,

貪欲法で考える• 全ての部分問題を解く必要があるのか?

• 実は,この問題ではある時点においてactivityを選択するとき,可能な候補の中で最も早く終了するものを選べば良い (貪欲的選択)

• 貪欲的選択であるactivity ak を選んだ場合,残る部分問題は1つ (ak終了時刻よりあとのactivityの集合の中から最適な部分集合を選ぶ)

この貪欲法は最適か?

• Theorem 16.1ある部分問題Skを考える.amをSkの中で最も早く終了するactivityだとする.するとamはSkの部分集合の中で要素数が最大のもののうちのどれかに含まれる

証明• Ak: Skの中で重ならない最大の部分集合

• aj : Akの中で最も早く終わるもの

• aj = am なら終了

• aj != am なら A’k = Ak - {aj} ∪ {am} とajとamを入れ替える. すると,Akはお互いに重ならず,amはajより早く終了するのでA’kもお互いに重ならず,|A’k| = |Ak|. つまりSkの最適な部分集合はamを含む

結論

• activity-seleciton 問題は貪欲法で最適解が求められる

• 貪欲法は基本的にトップダウン的ある選択をしてから,次の部分問題を特 (DPは,部分問題を解いてから選択をするボトムアップ式)

再帰的貪欲法• ボトムアップ式に考える

• s,f: 各activityの開始/終了時間の配列(ソート済) k=0からはじめてk=nの部分問題を解いて終了

• 全体として各acitivityは1回ずつ調べられるのでΘ(n)

ループによる解法• 先ほどのアルゴリズムは末尾再帰なのでループに直す事は簡単

貪欲法による解の構成方法1. 問題の最適な構造を決定する

2. 再帰的な解法を考える

3. その時貪欲的選択をした場合一つの部分問題だけ残ることを示す

4. 常に貪欲的選択をしても問題ないことを示す

5. 貪欲的な再帰的解法を実装する

6. 再帰的解法をループに変換する

もう少し単純化すると1. 問題をある一つの選択をした場合,一つの部分問

題が残るような形で表現する

2. 最適な解の中で貪欲的選択をするものがある事を示す

3. 貪欲的選択をし,残りの部分問題も同様に貪欲的選択をしていくことで最適解が構成できることを示す

いつ貪欲法が使えるか?

• 残念ながら単純に分かる方法はない

• ただし,貪欲的選択属性 (Greedy-choise property) と 最適部分構造 (optimal substructure) の2つが重要

Greedy-choise property• ある時点で最適な選択をすれば結果として最適解が得られる事

• 一般にDPでは,部分問題を解かなければ選択を決定できない=> ボトムアップで解く.トップダウンにしたければメモ化する

• 貪欲法では選択は部分問題によらない => トップダウン

Optimal substructure

• 最適解が部分問題の最適解を含む事

• 貪欲的選択をしたとき,残りの部分問題の最適解を合わせたものが最適解になるか考えることが必要

貪欲法 vs DP• 以下の2つの問題を考える

• 0-1 ナップサック問題n個の商品があり,i番目の商品は価値vi,重さwi Σwi ≦ W の制限かでviを最大化する商品集合は?

• 分数ナップサック問題0-1ナップサック問題と似ているが,商品の個数が分数で良い

ナップサック問題の性質• 両方ともoptimal-substructure 属性を持つ

• 0-1ナップサック問題において,合計の重さがWの最適解の中からある商品jを取り除いたとする.すると残りのW-wjの重さの商品はn-1個の商品集合の中から選んだ最適解

• 分数ナップサック問題では,jを重さwだけ取り除くと残りのW-wの商品集合はn-1個の商品集合と重さwj-w のjの中から選んだ最適集合

貪欲法は使えるか?

• 結論: 分数ナップサック問題は貪欲法で解く事ができるが,0-1ナップサック問題は貪欲法では解けない

分数ナップサック問題の解法

1. vi/wi を計算する

2. 貪欲的にvi/wiが最も高い商品から選んでいく

• 証明はExercise 16.2-1

0-1ナップサック問題では?• 貪欲法では解けない例量が離散的なので貪欲法では必ずしもナップサックを埋めらるわけではない

16.3 ハフマン符号• 符号化: a,b,cなどの文字を01で表現すること

• 文字符号化問題平均符号長をできるだけ短くして文字を符号化する文字の生成頻度は一般に異なるので上手くやれば効率的な符号化ができる => ハフマン符号

接頭符号(prefix code)

• ある符号語の接頭語が他の符号語になっていないことex) 1110 という符号語があったとき, 111 という符号語が別にあればそれは接頭符号でない

• 接頭符号なら,一意にデコード可能

木構造による表現

• 文字列を符号化するのに必要なビット数は,B(T) = Σc.freq * dt(c)ただしc.freqが文字cの頻度,dt(c)はcに対応する葉の深さ

ハフマン符号の構成

• ハフマン符号は,貪欲的方法で最適な接頭符号を背生成する

• アイディア: 先ほどの木構造を葉から構成する

ハフマン符号のアルゴリズム

ハフマン符号のアルゴリズム

• C: n個の文字の集合, c ∈ C, c.freq: cの頻度とする

• Qは頻度を基準とするプライオリティーキュー

ハフマン符号が最適であることの証明(1)

• Lemma 16.2Cを文字集合,c ∈ C の頻度をc.freqとする.xとyがCの中で最も頻度が低い文字のいずれかだとすると,xとyの符号語の長さが同じでかつxとyの最後のビットだけ異なるような最適な符号が存在するこれはハフマン符号がgreedy-choise属性を持つ事を示す

証明

• 証明のアイディア: 任意の最適な符号語を表す木を修正することでxとyが兄弟でかつ一番深い葉になるような最適な符号語を作成する

証明• 木Tの最も深い兄弟の葉をa,bとするa.freq ≦ b.freq, x.freq ≦ y.freq とするx,yは最小の頻度を持つのでx.freq ≦ a.freq, y.freq ≦ b.freq

• x.freq = b.freq なら a.freq = b.freq = x.freq=y.freq以降ではx.freq != b.freq (x != b) を考える

証明

• yとbを交換したときも同様

ハフマン符号が最適であることの証明(2)

• Lemma 16.3Cを文字集合,c ∈ C の頻度をc.freqとする.xとyをCの中で最小の頻度を持つ2つの文字とする.C’ = C - {x,y} ∪ {z} を考える.z.freq = x.freq + y.freq.T’をC’を表現する最適な符号語の一つだとすると,T’の葉ノードzをxとyを子に持つようなノードに変更したTはCの最適な符号語になる

証明• x,y を除いて dT(c) = dT’(c) (深さが同じ)

• dT(x) = dT’(z)+1, dT(y) = dT’(z)+1

• x.freq*dT(x) + y.freq*dT(y) = z.freq*dT’(z) + x.freq + y.freq

• B(T) = B(T’) + x.freq + y.freq

• Tが最適でなければ B(T’’) < B(T) になるT’’が存在 Lemma16.2よりT’’はxとyを葉ノードに持つような木T’’’にできる B(T’’’) = B(T’’) - x.freq - y.freq < B(T) - x.freq - y.freq = B(T’)

ハフマン符号が最適であることの証明(3)

• Theorem16.4ハフマン符号は最適な接頭符号を生成する

• [証] Lamma16.2及び16.3 から直ちに示される