SlideShare une entreprise Scribd logo
1  sur  29
ハフマン符号長の効率的な求め方
モチベーション ,[object Object],[object Object],[object Object],[object Object]
0.  a 10  4. e 22 1.  b 11  5. f 23 2.  c 2  6. g 5 3.  d 13  7. h 13 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 シンボルの数  n  に対してサイズ  2n  の配列 A を用意する。この配列で左上の表のハフマン木を表現することを考える 例 :  シンボル  d  のシンボル番号  ( 文字コード相当 )  は  3  で出現回数が  13  回
0.  a 10  4. e 22 1.  b 11  5. f 23 2.  c 2  6. g 5 3.  d 13  7. h 13 10 11 2 13 22 23 5 13 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 配列 A の右半分を出現回数で埋める。つまり、右半分の要素それぞれがハフマン木の葉に相当する。 シンボル番号を  i 、 i  の出現回数を  c i とすると  A[n + i] = c i 例えば、左上表からシンボル  b  は番号  1 、 c 1  = 11  なので  A[n + 1] = 11 (n = 8)
0.  a 10  4. e 22 1.  b 11  5. f 23 2.  c 2  6. g 5 3.  d 13  7. h 13 8 9 10 11 12 13 14 15 10 11 2 13 22 23 5 13 左半分を、各シンボルの葉へのポインタにする。具体的には、左側の要素の添え字がシンボル番号、値がポイントすべき右側の要素の添え字になる 例えば左上表からシンボル番号  i = 0  の  'a'  を考える。 A[0]  は右半分の要素の中で  'a'  の出現頻度に相当している要素を指す。よって  A[0] = 8  になる。 A[A[0]] = 10  とすれば  'a'  の出現頻度  10  が得られる 一般化すると  A[A[i]] = C i  になるように配列の左半分を埋めるということ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0.  a 10  4. e 22 1.  b 11  5. f 23 2.  c 2  6. g 5 3.  d 13  7. h 13 10 9 14 11 12 13 8 15 10 11 2 13 22 23 5 13 次に出現頻度の値を比較キーにして二分木ヒープ (※) を構成する。このとき右半分の出現頻度の配列、つまり葉で直接ヒープを構成するのではなく、左半分のポインタで間接的にヒープを構成する。右半分の値  ( 葉 )  は変更せず、左半分だけが必要に応じて入れ替わる。 これにより  A[0]  がヒープの根になる。つまり、 A[0]  は出現頻度最小の値をポイントすることになる ※ 配列で二分木ヒープを構成する場合、親の添え字を  i  とすると左の子は  2i + 1,  右の子は  2i + 2 。「親の指す値が常に子のそれよりも小さい」という制約を満たすのがヒープの条件 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0.  a 10  4. e 22 1.  b 11  5. f 23 2.  c 2  6. g 5 3.  d 13  7. h 13 9 14 11 12 13 8 15 10 11 13 22 23 5 13 いよいよハフマン木の構築を始める。通常のハフマン木構築アルゴリズム同様、出現頻度が最も小さい二つの値を (greedy  に ) 見つけたい。ひとつは、ヒープの根である  A[0]  がポイントする最小値である。 10 2 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0.  a 10  4. e 22 1.  b 11  5. f 23 2.  c 2  6. g 5 3.  d 13  7. h 13 9 14 11 12 13 8 15 10 11 13 22 23 5 13 一時変数  m1  に  A[0]  を取り出し、 10 2 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 10 m1
0.  a 10  4. e 22 1.  b 11  5. f 23 2.  c 2  6. g 5 3.  d 13  7. h 13 9 14 11 12 13 8 15 10 11 13 22 23 5 13 左半分の配列の末尾の値を先頭にコピー ( 上書き ) し、 15 2 10 m1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0.  a 10  4. e 22 1.  b 11  5. f 23 2.  c 2  6. g 5 3.  d 13  7. h 13 9 8 11 12 13 15 15 10 11 13 22 23 5 13 [0, n -1]  だった左半分の配列の範囲を一つ減らして  [0, n - 2]  の範囲でヒープを構成しなおす。 これで最初の最小値である  2 ( を指しているポインタ )  をヒープから取り出して、ヒープを再構成したことになる。 14 2 10 m1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0.  a 10  4. e 22 1.  b 11  5. f 23 2.  c 2  6. g 5 3.  d 13  7. h 13 9 8 11 12 13 15 15 10 11 13 22 23 5 13 次の最小値は構成しなおしたヒープの根  A[0]  にある。よって次の最小値は  A[A[0]] = A[14] = 5 14 2 10 m1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0.  a 10  4. e 22 1.  b 11  5. f 23 2.  c 2  6. g 5 3.  d 13  7. h 13 9 8 11 12 13 15 15 10 11 13 22 23 5 13 二つ目の最小値を一次変数  m2  に取り出す。 ( 今回はヒープの再構成はまだ走らせないことに注意 ) 14 2 10 m1 14 m2 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0.  a 10  4. e 22 1.  b 11  5. f 23 2.  c 2  6. g 5 3.  d 13  7. h 13 9 8 11 12 13 15 7 10 11 13 22 23 5 13 ここまでで最小の出現頻度の値二つが分かった。通常のハフマンアルゴリズムではここでこの二値の和を取ってできた節をハフマン木の新しい内部節  =  親とするわけだが、それと同等のことを行う。 ヒープから要素を一つ取り出して空いた領域  A[7]  があるので、そこに二値の和  A[m1] + A[m2] = 7  の値を入れる 14 2 10 m1 14 m2 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0.  a 10  4. e 22 1.  b 11  5. f 23 2.  c 2  6. g 5 3.  d 13  7. h 13 9 8 11 12 13 15 7 10 11 13 22 23 5 13 A[0]  の値は既に  m2  にコピーしてあり要らないので、そこから新しい要素をポイントする。 7 2 10 m1 14 m2 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0.  a 10  4. e 22 1.  b 11  5. f 23 2.  c 2  6. g 5 3.  d 13  7. h 13 9 8 11 12 13 15 7 10 11 13 22 23 7 13 最小値として扱った要素  A[m1]  と  A[m2]  も用済み。 A[m1] 、 A[m2]  からも新しい要素 ( つまり親 )  をポイントする。すなわち  A[m1] = A[m2] =  A[0] これで葉  ( もしくは内部節 ) から親を参照したことになる 7 7 10 m1 14 m2 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0.  a 10  4. e 22 1.  b 11  5. f 23 2.  c 2  6. g 5 3.  d 13  7. h 13 9 8 11 12 13 15 7 10 11 13 22 23 7 13 新しく追加した要素を加味して、左側のヒープを構成しなおす。 ( この場合、新しく追加した要素  A[7] = 7  は最小なのでヒープに変更はなし ) ここまでで、ハフマン木構築処理のうち、最小の二つの要素を取って和を取り新しい要素にし、ヒープを次の繰り返しに備えて再構築する、という手順が一回完了した。 7 7 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0.  a 10  4. e 22 1.  b 11  5. f 23 2.  c 2  6. g 5 3.  d 13  7. h 13 9 8 11 12 13 15 7 10 11 13 22 23 7 13 以下、ここまでの手順を繰り返す 根で最小値を指す  A[0]  を取り出し、 7 7 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 7 m1
0.  a 10  4. e 22 1.  b 11  5. f 23 2.  c 2  6. g 5 3.  d 13  7. h 13 9 8 11 12 13 15 7 10 11 13 22 23 7 13 15 7 左半分の配列の末尾の値を先頭にコピー ( 上書き ) し、 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 7 m1
0.  a 10  4. e 22 1.  b 11  5. f 23 2.  c 2  6. g 5 3.  d 13  7. h 13 9 15 11 12 13 15 7 10 11 13 22 23 7 13 8 7 [0, n -2]  だった左半分の配列の範囲を一つ減らして  [0, n - 3]  の範囲でヒープを構成しなおす 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 7 m1
0.  a 10  4. e 22 1.  b 11  5. f 23 2.  c 2  6. g 5 3.  d 13  7. h 13 9 15 11 12 13 15 7 10 11 13 22 23 7 13 8 7 二つ目の最小値を指すポインタを  m2  に取り出し、 8 m2 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 7 m1
0.  a 10  4. e 22 1.  b 11  5. f 23 2.  c 2  6. g 5 3.  d 13  7. h 13 9 15 11 12 13 17 7 10 11 13 22 23 7 13 8 7 A[m1] + A[m2] = 17  を、ヒープから要素を取り出したことで空いていた要素に入れる 8 m2 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 7 m1
0.  a 10  4. e 22 1.  b 11  5. f 23 2.  c 2  6. g 5 3.  d 13  7. h 13 9 15 11 12 13 17 6 6 11 13 22 23 7 13 6 7 用済みの要素である先頭、今回扱った二つの最小値要素から、今できた新しい要素をポイントする 8 m2 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 7 m1
0.  a 10  4. e 22 1.  b 11  5. f 23 2.  c 2  6. g 5 3.  d 13  7. h 13 11 15 6 12 13 17 6 6 11 13 22 23 7 13 9 7 ヒープを構成しなおす。 これでハフマン木構築の繰り返し 2 回目が完了。このまま繰り返していくと、ループのたびにヒープ ( 青の要素 ) とオリジナルの出現頻度値を保持していた要素 ( 橙色の要素 ) が少なくなっていき、親をポイントしている要素 ( 緑の要素 ) が増えていくことが直感的にわかる 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0.  a 10  4. e 22 1.  b 11  5. f 23 2.  c 2  6. g 5 3.  d 13  7. h 13 99 1 1 2 2 4 6 6 5 5 3 3 7 4 1 7 ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0.  a 10  4. e 22 1.  b 11  5. f 23 2.  c 2  6. g 5 3.  d 13  7. h 13 99 1 1 2 2 4 6 6 5 5 3 3 7 4 1 7 ,[object Object],[object Object],[object Object],[object Object],0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
99 1 1 2 2 4 6 6 5 5 3 3 7 4 1 7 ここで 子 -> 親はかならず右から左へ向かっている。ということは、逆に左から右、つまり先頭から末尾に向かうのは親から子に向かう動きになる。 この特徴を利用すると、左から順番に  A[i] = A[A[i]] + 1  していくだけで、 A[n + i]  にシンボル  i  の符号長が入る。これを理解するために動きを追ってみる。 まず根は  A[1] = 0  とする 0 1 1 2 2 4 6 6 5 5 3 3 7 4 1 7 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 1 1 2 2 4 6 6 5 5 3 3 7 4 1 7 次の要素  A[2]  は  1  で、この  1  は根である  A[1]  の添え字を指さしている。 さて、添え字を  1 -> 2  と移動してきたのは、左から右へ移動をしたということで、これはハフマン木の親から子を辿っていることに等しい。 ハフマン木では幹を一回辿るたびに符号長が  +1  されるわけだから、 ( 親が今辿った道までの符号長を記録していると考えると ) A[2]  までの符号長は親である  A[1]  の符号長  +1  である。 先に  A[1] = 0  としたのは、根は当然まだ幹を一度も辿ってないので、そこまでの符号長が  0  ということ。よって  A[2] = A[A[1]] + 1 = 0 + 1 0 1 1 2 2 4 6 6 5 5 3 3 7 4 1 7 同じように、 A[3] = 1 -> A[3] = A[A[1]] + 1 = 0 + 1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 1 1 2 2 4 6 6 5 5 3 3 7 4 1 7 A[4] = 2  ということは、 A[4]  へは親である  A[2]  から辿ってくるということ。従って  A[4]  での符号長は  A[4] = A[A[2]] + 1 このように、左から順番に  A[i] = A[A[i]] + 1  するということは、親からひとつ子を辿ったら、親が持っていた符号の長さに  +1  したことに等しい 2n  まで処理すると最終的に以下のようになる 0 1 1 2 2 3 4 4 3 3 2 2 5 3 1 5 先にも述べたように、シンボル  i  の葉に相当するのは  A[n + i] 。赤枠で囲った右半分の配列の中身が、各シンボルの符号長である。例えば、シンボル  c ( 番号 2)  の符号長は  A[n + i] = A[8 + 2] = 5 おしまい 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
参考文献 ,[object Object]

Contenu connexe

En vedette

Web-Gakkai Symposium 2010
Web-Gakkai Symposium 2010Web-Gakkai Symposium 2010
Web-Gakkai Symposium 2010Naoya Ito
 
Dijkstra Algorithm
Dijkstra AlgorithmDijkstra Algorithm
Dijkstra AlgorithmNaoya Ito
 
Introduction To Moco
Introduction To MocoIntroduction To Moco
Introduction To MocoNaoya Ito
 
Titanium Mobile
Titanium MobileTitanium Mobile
Titanium MobileNaoya Ito
 
Introduction to Algorithms#24 Shortest-Paths Problem
Introduction to Algorithms#24 Shortest-Paths ProblemIntroduction to Algorithms#24 Shortest-Paths Problem
Introduction to Algorithms#24 Shortest-Paths ProblemNaoya Ito
 
081108huge_data.ppt
081108huge_data.ppt081108huge_data.ppt
081108huge_data.pptNaoya Ito
 
about Thrift
about Thriftabout Thrift
about ThriftNaoya Ito
 
SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...
SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...
SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...Naoya Ito
 
スペルミス修正プログラムを作ろう
スペルミス修正プログラムを作ろうスペルミス修正プログラムを作ろう
スペルミス修正プログラムを作ろうNaoya Ito
 
はてなブックマークのシステムについて
はてなブックマークのシステムについてはてなブックマークのシステムについて
はてなブックマークのシステムについてNaoya Ito
 
Perlで圧縮
Perlで圧縮Perlで圧縮
Perlで圧縮Naoya Ito
 
Sphinx で手軽に作るドキュメント
Sphinx で手軽に作るドキュメントSphinx で手軽に作るドキュメント
Sphinx で手軽に作るドキュメントGo Yamada
 
APIドキュメントの話 #sphinxjp
APIドキュメントの話 #sphinxjpAPIドキュメントの話 #sphinxjp
APIドキュメントの話 #sphinxjpTakeshi Komiya
 
Sphinxで社内勉強会(Git)の
資料を作ってみた
Sphinxで社内勉強会(Git)の
資料を作ってみたSphinxで社内勉強会(Git)の
資料を作ってみた
Sphinxで社内勉強会(Git)の
資料を作ってみたTaku SHIMIZU
 
ドキュメントシステムはこれを使え2015年版
ドキュメントシステムはこれを使え2015年版ドキュメントシステムはこれを使え2015年版
ドキュメントシステムはこれを使え2015年版Keiichiro Shikano
 
How to read linux kernel
How to read linux kernelHow to read linux kernel
How to read linux kernelNaoya Ito
 
オープンソースの情報共有の仕組み"Knowledge"のご紹介
オープンソースの情報共有の仕組み"Knowledge"のご紹介オープンソースの情報共有の仕組み"Knowledge"のご紹介
オープンソースの情報共有の仕組み"Knowledge"のご紹介koda3
 

En vedette (17)

Web-Gakkai Symposium 2010
Web-Gakkai Symposium 2010Web-Gakkai Symposium 2010
Web-Gakkai Symposium 2010
 
Dijkstra Algorithm
Dijkstra AlgorithmDijkstra Algorithm
Dijkstra Algorithm
 
Introduction To Moco
Introduction To MocoIntroduction To Moco
Introduction To Moco
 
Titanium Mobile
Titanium MobileTitanium Mobile
Titanium Mobile
 
Introduction to Algorithms#24 Shortest-Paths Problem
Introduction to Algorithms#24 Shortest-Paths ProblemIntroduction to Algorithms#24 Shortest-Paths Problem
Introduction to Algorithms#24 Shortest-Paths Problem
 
081108huge_data.ppt
081108huge_data.ppt081108huge_data.ppt
081108huge_data.ppt
 
about Thrift
about Thriftabout Thrift
about Thrift
 
SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...
SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...
SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...
 
スペルミス修正プログラムを作ろう
スペルミス修正プログラムを作ろうスペルミス修正プログラムを作ろう
スペルミス修正プログラムを作ろう
 
はてなブックマークのシステムについて
はてなブックマークのシステムについてはてなブックマークのシステムについて
はてなブックマークのシステムについて
 
Perlで圧縮
Perlで圧縮Perlで圧縮
Perlで圧縮
 
Sphinx で手軽に作るドキュメント
Sphinx で手軽に作るドキュメントSphinx で手軽に作るドキュメント
Sphinx で手軽に作るドキュメント
 
APIドキュメントの話 #sphinxjp
APIドキュメントの話 #sphinxjpAPIドキュメントの話 #sphinxjp
APIドキュメントの話 #sphinxjp
 
Sphinxで社内勉強会(Git)の
資料を作ってみた
Sphinxで社内勉強会(Git)の
資料を作ってみたSphinxで社内勉強会(Git)の
資料を作ってみた
Sphinxで社内勉強会(Git)の
資料を作ってみた
 
ドキュメントシステムはこれを使え2015年版
ドキュメントシステムはこれを使え2015年版ドキュメントシステムはこれを使え2015年版
ドキュメントシステムはこれを使え2015年版
 
How to read linux kernel
How to read linux kernelHow to read linux kernel
How to read linux kernel
 
オープンソースの情報共有の仕組み"Knowledge"のご紹介
オープンソースの情報共有の仕組み"Knowledge"のご紹介オープンソースの情報共有の仕組み"Knowledge"のご紹介
オープンソースの情報共有の仕組み"Knowledge"のご紹介
 

Dernier

部内勉強会(IT用語ざっくり学習) 実施日:2024年5月17日(金) 対象者:営業部社員
部内勉強会(IT用語ざっくり学習) 実施日:2024年5月17日(金) 対象者:営業部社員部内勉強会(IT用語ざっくり学習) 実施日:2024年5月17日(金) 対象者:営業部社員
部内勉強会(IT用語ざっくり学習) 実施日:2024年5月17日(金) 対象者:営業部社員Sadaomi Nishi
 
5/22 第23回 Customer系エンジニア座談会のスライド 公開用 西口瑛一
5/22 第23回 Customer系エンジニア座談会のスライド 公開用 西口瑛一5/22 第23回 Customer系エンジニア座談会のスライド 公開用 西口瑛一
5/22 第23回 Customer系エンジニア座談会のスライド 公開用 西口瑛一瑛一 西口
 
2024年5月25日Serverless Meetup大阪 アプリケーションをどこで動かすべきなのか.pptx
2024年5月25日Serverless Meetup大阪 アプリケーションをどこで動かすべきなのか.pptx2024年5月25日Serverless Meetup大阪 アプリケーションをどこで動かすべきなのか.pptx
2024年5月25日Serverless Meetup大阪 アプリケーションをどこで動かすべきなのか.pptxssuserbefd24
 
論文紹介: Exploiting semantic segmentation to boost reinforcement learning in vid...
論文紹介: Exploiting semantic segmentation to boost reinforcement learning in vid...論文紹介: Exploiting semantic segmentation to boost reinforcement learning in vid...
論文紹介: Exploiting semantic segmentation to boost reinforcement learning in vid...atsushi061452
 
クラウド時代におけるSREとUPWARDの取組ーUPWARD株式会社 CTO門畑
クラウド時代におけるSREとUPWARDの取組ーUPWARD株式会社 CTO門畑クラウド時代におけるSREとUPWARDの取組ーUPWARD株式会社 CTO門畑
クラウド時代におけるSREとUPWARDの取組ーUPWARD株式会社 CTO門畑Akihiro Kadohata
 
Amazon Cognitoで実装するパスキー (Security-JAWS【第33回】 勉強会)
Amazon Cognitoで実装するパスキー (Security-JAWS【第33回】 勉強会)Amazon Cognitoで実装するパスキー (Security-JAWS【第33回】 勉強会)
Amazon Cognitoで実装するパスキー (Security-JAWS【第33回】 勉強会)keikoitakurag
 
論文紹介:ViTPose: Simple Vision Transformer Baselines for Human Pose Estimation
論文紹介:ViTPose: Simple Vision Transformer Baselines for Human Pose Estimation論文紹介:ViTPose: Simple Vision Transformer Baselines for Human Pose Estimation
論文紹介:ViTPose: Simple Vision Transformer Baselines for Human Pose EstimationToru Tamaki
 
Intranet Development v1.0 (TSG LIVE! 12 LT )
Intranet Development v1.0 (TSG LIVE! 12 LT )Intranet Development v1.0 (TSG LIVE! 12 LT )
Intranet Development v1.0 (TSG LIVE! 12 LT )iwashiira2ctf
 
論文紹介:Deep Occlusion-Aware Instance Segmentation With Overlapping BiLayers
論文紹介:Deep Occlusion-Aware Instance Segmentation With Overlapping BiLayers論文紹介:Deep Occlusion-Aware Instance Segmentation With Overlapping BiLayers
論文紹介:Deep Occlusion-Aware Instance Segmentation With Overlapping BiLayersToru Tamaki
 
ロボットマニピュレーションの作業・動作計画 / rosjp_planning_for_robotic_manipulation_20240521
ロボットマニピュレーションの作業・動作計画 / rosjp_planning_for_robotic_manipulation_20240521ロボットマニピュレーションの作業・動作計画 / rosjp_planning_for_robotic_manipulation_20240521
ロボットマニピュレーションの作業・動作計画 / rosjp_planning_for_robotic_manipulation_20240521Satoshi Makita
 
20240523_IoTLT_vol111_kitazaki_v1___.pdf
20240523_IoTLT_vol111_kitazaki_v1___.pdf20240523_IoTLT_vol111_kitazaki_v1___.pdf
20240523_IoTLT_vol111_kitazaki_v1___.pdfAyachika Kitazaki
 
論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes
論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes
論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizesatsushi061452
 

Dernier (12)

部内勉強会(IT用語ざっくり学習) 実施日:2024年5月17日(金) 対象者:営業部社員
部内勉強会(IT用語ざっくり学習) 実施日:2024年5月17日(金) 対象者:営業部社員部内勉強会(IT用語ざっくり学習) 実施日:2024年5月17日(金) 対象者:営業部社員
部内勉強会(IT用語ざっくり学習) 実施日:2024年5月17日(金) 対象者:営業部社員
 
5/22 第23回 Customer系エンジニア座談会のスライド 公開用 西口瑛一
5/22 第23回 Customer系エンジニア座談会のスライド 公開用 西口瑛一5/22 第23回 Customer系エンジニア座談会のスライド 公開用 西口瑛一
5/22 第23回 Customer系エンジニア座談会のスライド 公開用 西口瑛一
 
2024年5月25日Serverless Meetup大阪 アプリケーションをどこで動かすべきなのか.pptx
2024年5月25日Serverless Meetup大阪 アプリケーションをどこで動かすべきなのか.pptx2024年5月25日Serverless Meetup大阪 アプリケーションをどこで動かすべきなのか.pptx
2024年5月25日Serverless Meetup大阪 アプリケーションをどこで動かすべきなのか.pptx
 
論文紹介: Exploiting semantic segmentation to boost reinforcement learning in vid...
論文紹介: Exploiting semantic segmentation to boost reinforcement learning in vid...論文紹介: Exploiting semantic segmentation to boost reinforcement learning in vid...
論文紹介: Exploiting semantic segmentation to boost reinforcement learning in vid...
 
クラウド時代におけるSREとUPWARDの取組ーUPWARD株式会社 CTO門畑
クラウド時代におけるSREとUPWARDの取組ーUPWARD株式会社 CTO門畑クラウド時代におけるSREとUPWARDの取組ーUPWARD株式会社 CTO門畑
クラウド時代におけるSREとUPWARDの取組ーUPWARD株式会社 CTO門畑
 
Amazon Cognitoで実装するパスキー (Security-JAWS【第33回】 勉強会)
Amazon Cognitoで実装するパスキー (Security-JAWS【第33回】 勉強会)Amazon Cognitoで実装するパスキー (Security-JAWS【第33回】 勉強会)
Amazon Cognitoで実装するパスキー (Security-JAWS【第33回】 勉強会)
 
論文紹介:ViTPose: Simple Vision Transformer Baselines for Human Pose Estimation
論文紹介:ViTPose: Simple Vision Transformer Baselines for Human Pose Estimation論文紹介:ViTPose: Simple Vision Transformer Baselines for Human Pose Estimation
論文紹介:ViTPose: Simple Vision Transformer Baselines for Human Pose Estimation
 
Intranet Development v1.0 (TSG LIVE! 12 LT )
Intranet Development v1.0 (TSG LIVE! 12 LT )Intranet Development v1.0 (TSG LIVE! 12 LT )
Intranet Development v1.0 (TSG LIVE! 12 LT )
 
論文紹介:Deep Occlusion-Aware Instance Segmentation With Overlapping BiLayers
論文紹介:Deep Occlusion-Aware Instance Segmentation With Overlapping BiLayers論文紹介:Deep Occlusion-Aware Instance Segmentation With Overlapping BiLayers
論文紹介:Deep Occlusion-Aware Instance Segmentation With Overlapping BiLayers
 
ロボットマニピュレーションの作業・動作計画 / rosjp_planning_for_robotic_manipulation_20240521
ロボットマニピュレーションの作業・動作計画 / rosjp_planning_for_robotic_manipulation_20240521ロボットマニピュレーションの作業・動作計画 / rosjp_planning_for_robotic_manipulation_20240521
ロボットマニピュレーションの作業・動作計画 / rosjp_planning_for_robotic_manipulation_20240521
 
20240523_IoTLT_vol111_kitazaki_v1___.pdf
20240523_IoTLT_vol111_kitazaki_v1___.pdf20240523_IoTLT_vol111_kitazaki_v1___.pdf
20240523_IoTLT_vol111_kitazaki_v1___.pdf
 
論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes
論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes
論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes
 

090518computing Huffman Code Length

  • 2.
  • 3. 0. a 10 4. e 22 1. b 11 5. f 23 2. c 2 6. g 5 3. d 13 7. h 13 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 シンボルの数 n に対してサイズ 2n の配列 A を用意する。この配列で左上の表のハフマン木を表現することを考える 例 : シンボル d のシンボル番号 ( 文字コード相当 ) は 3 で出現回数が 13 回
  • 4. 0. a 10 4. e 22 1. b 11 5. f 23 2. c 2 6. g 5 3. d 13 7. h 13 10 11 2 13 22 23 5 13 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 配列 A の右半分を出現回数で埋める。つまり、右半分の要素それぞれがハフマン木の葉に相当する。 シンボル番号を i 、 i の出現回数を c i とすると A[n + i] = c i 例えば、左上表からシンボル b は番号 1 、 c 1 = 11 なので A[n + 1] = 11 (n = 8)
  • 5. 0. a 10 4. e 22 1. b 11 5. f 23 2. c 2 6. g 5 3. d 13 7. h 13 8 9 10 11 12 13 14 15 10 11 2 13 22 23 5 13 左半分を、各シンボルの葉へのポインタにする。具体的には、左側の要素の添え字がシンボル番号、値がポイントすべき右側の要素の添え字になる 例えば左上表からシンボル番号 i = 0 の 'a' を考える。 A[0] は右半分の要素の中で 'a' の出現頻度に相当している要素を指す。よって A[0] = 8 になる。 A[A[0]] = 10 とすれば 'a' の出現頻度 10 が得られる 一般化すると A[A[i]] = C i になるように配列の左半分を埋めるということ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  • 6. 0. a 10 4. e 22 1. b 11 5. f 23 2. c 2 6. g 5 3. d 13 7. h 13 10 9 14 11 12 13 8 15 10 11 2 13 22 23 5 13 次に出現頻度の値を比較キーにして二分木ヒープ (※) を構成する。このとき右半分の出現頻度の配列、つまり葉で直接ヒープを構成するのではなく、左半分のポインタで間接的にヒープを構成する。右半分の値 ( 葉 ) は変更せず、左半分だけが必要に応じて入れ替わる。 これにより A[0] がヒープの根になる。つまり、 A[0] は出現頻度最小の値をポイントすることになる ※ 配列で二分木ヒープを構成する場合、親の添え字を i とすると左の子は 2i + 1, 右の子は 2i + 2 。「親の指す値が常に子のそれよりも小さい」という制約を満たすのがヒープの条件 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  • 7. 0. a 10 4. e 22 1. b 11 5. f 23 2. c 2 6. g 5 3. d 13 7. h 13 9 14 11 12 13 8 15 10 11 13 22 23 5 13 いよいよハフマン木の構築を始める。通常のハフマン木構築アルゴリズム同様、出現頻度が最も小さい二つの値を (greedy に ) 見つけたい。ひとつは、ヒープの根である A[0] がポイントする最小値である。 10 2 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  • 8. 0. a 10 4. e 22 1. b 11 5. f 23 2. c 2 6. g 5 3. d 13 7. h 13 9 14 11 12 13 8 15 10 11 13 22 23 5 13 一時変数 m1 に A[0] を取り出し、 10 2 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 10 m1
  • 9. 0. a 10 4. e 22 1. b 11 5. f 23 2. c 2 6. g 5 3. d 13 7. h 13 9 14 11 12 13 8 15 10 11 13 22 23 5 13 左半分の配列の末尾の値を先頭にコピー ( 上書き ) し、 15 2 10 m1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  • 10. 0. a 10 4. e 22 1. b 11 5. f 23 2. c 2 6. g 5 3. d 13 7. h 13 9 8 11 12 13 15 15 10 11 13 22 23 5 13 [0, n -1] だった左半分の配列の範囲を一つ減らして [0, n - 2] の範囲でヒープを構成しなおす。 これで最初の最小値である 2 ( を指しているポインタ ) をヒープから取り出して、ヒープを再構成したことになる。 14 2 10 m1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  • 11. 0. a 10 4. e 22 1. b 11 5. f 23 2. c 2 6. g 5 3. d 13 7. h 13 9 8 11 12 13 15 15 10 11 13 22 23 5 13 次の最小値は構成しなおしたヒープの根 A[0] にある。よって次の最小値は A[A[0]] = A[14] = 5 14 2 10 m1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  • 12. 0. a 10 4. e 22 1. b 11 5. f 23 2. c 2 6. g 5 3. d 13 7. h 13 9 8 11 12 13 15 15 10 11 13 22 23 5 13 二つ目の最小値を一次変数 m2 に取り出す。 ( 今回はヒープの再構成はまだ走らせないことに注意 ) 14 2 10 m1 14 m2 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  • 13. 0. a 10 4. e 22 1. b 11 5. f 23 2. c 2 6. g 5 3. d 13 7. h 13 9 8 11 12 13 15 7 10 11 13 22 23 5 13 ここまでで最小の出現頻度の値二つが分かった。通常のハフマンアルゴリズムではここでこの二値の和を取ってできた節をハフマン木の新しい内部節 = 親とするわけだが、それと同等のことを行う。 ヒープから要素を一つ取り出して空いた領域 A[7] があるので、そこに二値の和 A[m1] + A[m2] = 7 の値を入れる 14 2 10 m1 14 m2 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  • 14. 0. a 10 4. e 22 1. b 11 5. f 23 2. c 2 6. g 5 3. d 13 7. h 13 9 8 11 12 13 15 7 10 11 13 22 23 5 13 A[0] の値は既に m2 にコピーしてあり要らないので、そこから新しい要素をポイントする。 7 2 10 m1 14 m2 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  • 15. 0. a 10 4. e 22 1. b 11 5. f 23 2. c 2 6. g 5 3. d 13 7. h 13 9 8 11 12 13 15 7 10 11 13 22 23 7 13 最小値として扱った要素 A[m1] と A[m2] も用済み。 A[m1] 、 A[m2] からも新しい要素 ( つまり親 ) をポイントする。すなわち A[m1] = A[m2] = A[0] これで葉 ( もしくは内部節 ) から親を参照したことになる 7 7 10 m1 14 m2 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  • 16. 0. a 10 4. e 22 1. b 11 5. f 23 2. c 2 6. g 5 3. d 13 7. h 13 9 8 11 12 13 15 7 10 11 13 22 23 7 13 新しく追加した要素を加味して、左側のヒープを構成しなおす。 ( この場合、新しく追加した要素 A[7] = 7 は最小なのでヒープに変更はなし ) ここまでで、ハフマン木構築処理のうち、最小の二つの要素を取って和を取り新しい要素にし、ヒープを次の繰り返しに備えて再構築する、という手順が一回完了した。 7 7 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  • 17. 0. a 10 4. e 22 1. b 11 5. f 23 2. c 2 6. g 5 3. d 13 7. h 13 9 8 11 12 13 15 7 10 11 13 22 23 7 13 以下、ここまでの手順を繰り返す 根で最小値を指す A[0] を取り出し、 7 7 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 7 m1
  • 18. 0. a 10 4. e 22 1. b 11 5. f 23 2. c 2 6. g 5 3. d 13 7. h 13 9 8 11 12 13 15 7 10 11 13 22 23 7 13 15 7 左半分の配列の末尾の値を先頭にコピー ( 上書き ) し、 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 7 m1
  • 19. 0. a 10 4. e 22 1. b 11 5. f 23 2. c 2 6. g 5 3. d 13 7. h 13 9 15 11 12 13 15 7 10 11 13 22 23 7 13 8 7 [0, n -2] だった左半分の配列の範囲を一つ減らして [0, n - 3] の範囲でヒープを構成しなおす 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 7 m1
  • 20. 0. a 10 4. e 22 1. b 11 5. f 23 2. c 2 6. g 5 3. d 13 7. h 13 9 15 11 12 13 15 7 10 11 13 22 23 7 13 8 7 二つ目の最小値を指すポインタを m2 に取り出し、 8 m2 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 7 m1
  • 21. 0. a 10 4. e 22 1. b 11 5. f 23 2. c 2 6. g 5 3. d 13 7. h 13 9 15 11 12 13 17 7 10 11 13 22 23 7 13 8 7 A[m1] + A[m2] = 17 を、ヒープから要素を取り出したことで空いていた要素に入れる 8 m2 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 7 m1
  • 22. 0. a 10 4. e 22 1. b 11 5. f 23 2. c 2 6. g 5 3. d 13 7. h 13 9 15 11 12 13 17 6 6 11 13 22 23 7 13 6 7 用済みの要素である先頭、今回扱った二つの最小値要素から、今できた新しい要素をポイントする 8 m2 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 7 m1
  • 23. 0. a 10 4. e 22 1. b 11 5. f 23 2. c 2 6. g 5 3. d 13 7. h 13 11 15 6 12 13 17 6 6 11 13 22 23 7 13 9 7 ヒープを構成しなおす。 これでハフマン木構築の繰り返し 2 回目が完了。このまま繰り返していくと、ループのたびにヒープ ( 青の要素 ) とオリジナルの出現頻度値を保持していた要素 ( 橙色の要素 ) が少なくなっていき、親をポイントしている要素 ( 緑の要素 ) が増えていくことが直感的にわかる 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  • 24.
  • 25.
  • 26. 99 1 1 2 2 4 6 6 5 5 3 3 7 4 1 7 ここで 子 -> 親はかならず右から左へ向かっている。ということは、逆に左から右、つまり先頭から末尾に向かうのは親から子に向かう動きになる。 この特徴を利用すると、左から順番に A[i] = A[A[i]] + 1 していくだけで、 A[n + i] にシンボル i の符号長が入る。これを理解するために動きを追ってみる。 まず根は A[1] = 0 とする 0 1 1 2 2 4 6 6 5 5 3 3 7 4 1 7 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  • 27. 0 1 1 2 2 4 6 6 5 5 3 3 7 4 1 7 次の要素 A[2] は 1 で、この 1 は根である A[1] の添え字を指さしている。 さて、添え字を 1 -> 2 と移動してきたのは、左から右へ移動をしたということで、これはハフマン木の親から子を辿っていることに等しい。 ハフマン木では幹を一回辿るたびに符号長が +1 されるわけだから、 ( 親が今辿った道までの符号長を記録していると考えると ) A[2] までの符号長は親である A[1] の符号長 +1 である。 先に A[1] = 0 としたのは、根は当然まだ幹を一度も辿ってないので、そこまでの符号長が 0 ということ。よって A[2] = A[A[1]] + 1 = 0 + 1 0 1 1 2 2 4 6 6 5 5 3 3 7 4 1 7 同じように、 A[3] = 1 -> A[3] = A[A[1]] + 1 = 0 + 1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  • 28. 0 1 1 2 2 4 6 6 5 5 3 3 7 4 1 7 A[4] = 2 ということは、 A[4] へは親である A[2] から辿ってくるということ。従って A[4] での符号長は A[4] = A[A[2]] + 1 このように、左から順番に A[i] = A[A[i]] + 1 するということは、親からひとつ子を辿ったら、親が持っていた符号の長さに +1 したことに等しい 2n まで処理すると最終的に以下のようになる 0 1 1 2 2 3 4 4 3 3 2 2 5 3 1 5 先にも述べたように、シンボル i の葉に相当するのは A[n + i] 。赤枠で囲った右半分の配列の中身が、各シンボルの符号長である。例えば、シンボル c ( 番号 2) の符号長は A[n + i] = A[8 + 2] = 5 おしまい 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  • 29.