【文献】
Veli MAKINEN et al.,Storage and Retrieval of Highly Repetitive Sequence Collections [online],Journal of Computational Biology,2010年 4月 8日,17(3),p.281-308,[retrieved on 2015-06-09],URL,http://jltsiren.kapsi.fi/papers/Maekinen2010.pdf
【文献】
岡野原 大輔,圧縮したまま検索,情報処理,日本,一般社団法人情報処理学会,2012年 4月15日,第53巻 第5号,p.504-512
【文献】
岡野原 大輔,大規模文字列解析の理論と実践,電子情報通信学会技術研究報告,日本,社団法人電子情報通信学会,2010年 6月 7日,第110巻 第76号,p.15-22
【文献】
定兼 邦彦,大規模データ処理のための簡潔データ構造,情報処理,日本,社団法人情報処理学会,2007年 8月15日,第48巻 第8号,p.899-902
(58)【調査した分野】(Int.Cl.,DB名)
各連続区間について、当該連続区間の位置と、前記第1の値の出現数と、前記第2の値の出現数との3つの値のうち、少なくとも2つの値が、前記第1のデータ、前記第2のデータ、又は前記第3のデータによって特定され、且つ、特定される前記少なくとも2つの値は、当該連続区間の位置によって変化する、
請求項1に記載の情報処理装置。
前記データ構造は、前記第1のデータが特定する前記位置、前記第2のデータが特定する前記第1の値の出現数、前記第3のデータが特定する前記第2の値の出現数、それぞれを、単調増加する数列とみなすことによって圧縮され、圧縮された状態で、前記記憶部に記憶されている、
請求項1〜5のいずれかに記載の情報処理装置。
前記第1のデータが位置を特定した連続区間と、前記第2のデータが前記第1の値の出現数を特定した連続区間と、前記第2のデータが前記第2の値の出現数を特定した連続区間とのうち、2つが一致している、又はそれぞれが互いに異なっている、
請求項7に記載のデータ構造。
第1の値と第2の値とで構成されたビット列上で、前記第1の値又は前記第2の値が1個以上連続する連続区間の全部又は一部の位置を特定する、第1のデータと、前記連続区間の一部について、前記ビット列上で、前記ビット列の先頭から当該連続区間までに出現した第1の値の出現数を特定する、第2のデータと、前記連続区間の一部について、前記ビット列上で、前記ビット列の先頭から当該連続区間までに出現した第2の値の出現数を特定する、第3のデータと、を有するデータ構造を用いた情報処理方法であって、
(a)自然数が入力されたときに、前記ビット列上の位置であって、先頭から当該位置までに含まれる前記第1の値の個数が前記自然数と等しくなる第1のセレクト位置を、前記第1のデータ、前記第2のデータ、及び前記第3のデータを用いて、特定する、ステップと、
(b)自然数が入力されたときに、前記ビット列上の位置であって、先頭から当該位置までに含まれる前記第2の値の個数が前記自然数と等しくなる第2のセレクト位置を、前記第1のデータ、前記第2のデータ、及び前記第3のデータを用いて、特定する、ステップと、
を有する、ことを特徴とする情報処理方法。
各連続区間について、当該連続区間の位置と、前記第1の値の出現数と、前記第2の値の出現数との3つの値のうち、少なくとも2つの値が、前記第1のデータ、前記第2のデータ、又は前記第3のデータによって特定され、且つ、特定される前記少なくとも2つの値は、当該連続区間の位置によって変化する、
請求項10に記載の情報処理方法。
各連続区間について、当該連続区間の位置と、前記第1の値の出現数と、前記第2の値の出現数との3つの値のうち、少なくとも2つの値が、前記第1のデータ、前記第2のデータ、又は前記第3のデータによって特定され、且つ、特定される前記少なくとも2つの値は、当該連続区間の位置によって変化する、
請求項15に記載のプログラム。
前記(a)のステップにおいて、前記データ構造は、前記第1のデータが特定する前記位置、前記第2のデータが特定する前記第1の値の出現数、前記第3のデータが特定する前記第2の値の出現数、それぞれを、単調増加する数列とみなすことによって圧縮され、圧縮された状態で、前記記憶装置に格納される、
請求項15〜19のいずれかに記載のプログラム。
【技術分野】
【0001】
本発明は、データ構造、情報処理装置、情報処理方法、及びこれらを実現するためのプログラム記録媒体に関し、特には、ビット列上での効率的な計算を行うための、データ構造、情報処理装置、情報処理方法、及びプログラム記録媒体に関する。
【0002】
近年、完備辞書(fully indexable dictionary)というデータ構造が注目されている(例えば、非特許文献1参照)。完備辞書は、長さnのビット列Bに対してrank、selectと呼ばれる2種類の操作をサポートするデータ構造である。この2種類の操作は以下のように定義される。但し、以下において、ビット列Bの最初の要素をB[0]、ビット列Bの最後の要素をB[n-1]とし、ビット列B上のi番目の要素からj番目の要素からなる部分列をB[i,j]で表し、終端であるj番目の要素を含まない場合の部分列をB[i,j)で表すものとする。
【0003】
まず、「rank1(B,i)」は、B[0,i)の範囲に存在する1の数を返す操作である。「rank0(B,i)」は、B[0,i)の範囲に存在する0の数を返す操作である。select1(B,i)は、ビット列B上でi+1番目の1が出現する位置を返す操作である。select0(B,i)は、ビット列B上でi+1番目の0が出現する位置を返す操作である。
【0004】
なお、この他に、完備辞書では、access(B,i)というi番目の要素の値B[i]を返す操作がサポートされることもある。また、完備辞書は、文献によって、「簡潔ビットベクトル」、「rank / select dictionary」等と呼ばれることがあるが、いずれも同じものを意味している。
【0005】
ところで、完備辞書は、簡潔データ構造(succinct data structure)と呼ばれる省スペースなデータ構造を作るための基礎となっている。簡潔データ構造は、木構造、グラフ構造、テキストデータなど、様々なデータ構造を小さなデータ構造で表現するものであり、大規模データを扱うための技術として注目されている。更に、簡潔データ構造のサイズは、基礎となる完備辞書のサイズに依存する。そのため、完備辞書を、極力小さなサイズで実現することが、大規模データを扱う上で重要となる。以下に、この点について説明する。
【0006】
まず、元となるビット列Bを圧縮せずにそのまま保持しつつ、ビット列に補助構造を付加することで完備辞書を実現する方法が知られている。これは下記の非特許文献1の「4.2.3 密な場合」で紹介されている手法である。なお、本明細書では、このような圧縮がされていない完備辞書を「無圧縮な完備辞書」と表記し、予め与えられているものとする。
【0007】
一方、元のビット列において、1と0との出現の分布に特徴がある場合、ビット列を圧縮できる可能性がある。このような場合に、ビット列を圧縮しつつ、そのビット列の完備辞書を実現する手法が知られている。このような手法は、元のビット列Bよりも小さいサイズで完備辞書を実現できる利点がある。但し、完備辞書の圧縮方法は、元のビット列における1と0との分布によって異なっている。
【0008】
まず、初めに、要素のほとんどが0で構成され、1が稀にしか存在していないビット列の完備辞書の圧縮方法について説明する。ここでは、このようなビット列を「疎なビット列」と呼ぶ。たとえば、「0000010000001000000」のようなビット列が挙げられる。
【0009】
このとき、1の出現位置に注目することで、このビット列を圧縮しつつ、完備辞書を実現する方法が知られている。ここでは非特許文献1(「4.2.4 疎な場合」を参照)に開示されている手法を紹介する。
【0010】
この手法は「Elias-Fano representation」又は「sdarray」と呼ばれている。ビット列Bには、m個の1が含まれているものとする。ビット列が疎な場合とは、m<<nが成り立つ場合である。このとき、1の出現する位置を収めた、長さmの単調増加配列Pを考える。P[i] = select1(B,i)と定義される。なお、nはビット列の長さを表している。
【0011】
このとき、床関数をfloor()で表すと、p= floor(log(n/m))と定義される。但し、本明細書では、logの底を2とする。そして、以下のような長さmの配列Lと配列Hとを考える。
配列L[i]は、単調増加配列P[i]の下位pビットを保持し、配列H[i]は、単調増加配列P[i]の残りの上位ビットを保持するとする。すなわち、P[i] =2p・H[i] + L[i]が成立するとする。なお、このとき、配列Hは、広義単調増加列である。
【0012】
ここで、D[i]=H[i]-H[i-1]+1となる配列Dを考える。配列Dは正整数列である。また、この配列Dを単進符号で表したビット列Eを考える。このビット列は長さ2mで表される。このとき、ビット列Eについての完備辞書を構築することができる。ビット列Eの完備辞書は2m+o(m)ビットで実現できる。
【0013】
疎なビット列の完備辞書は、配列Eの無圧縮な完備辞書と、ビット配列Lとを組み合わせたものである。よって、配列Lはm log(n/m)ビットであり、配列Eの完備辞書は2m+o(m)ビットで表されるため、合計のサイズはm log(n/m)+2m+o(m)ビットである。このサイズは、m<<nが成り立つ疎な場合において、元のnビットの配列Bよりも小さくなる。
【0014】
この非特許文献1に開示され方法で実現された完備辞書において、select1(B,i)は下記の数1によって計算することができる。
【0015】
【数1】
【0016】
また、rank1(B,i)は、以下のように計算できる。初めに、ビット列Eの完備辞書を用いて「0」の数をカウントすることで、iの上位ビットと同じかそれより大きくなるような最小の上位ビットH[t]の位置tを求める。このH[t]と対応する下位ビットL[t]を足し合わせることでP[t]の値を求める。この後、tを1づつ増やしていき、iを超えない最大のP[t]を求めれば、そのときtの値が、位置iまでに存在する「1」の数を表す。
【0017】
このとき、ひとたびP[t]の値を求めた後は、P[t-1]の値又はP[t+1]の値を求めるときに、配列E及び配列Lを初めから探索しなおさなくても計算できることに注意する。何故なら、配列L及び配列Eにおいて、P[t]に関する値が保持されている記憶領域は既に見つかっているので、その前後の値を調べればP[t-1]又はP[t+1]の値は容易に計算できるからである。また、このように、疎なビット列の完備辞書は、単調増加配列Pを効率的に表現したものと見なすこともできる。
【0018】
その他に、疎なビット列の完備辞書を表現する方法としては、非特許文献3に開示されている手法も挙げられる。非特許文献1及び非特許文献3のいずれに開示されている手法を用いても、疎なビット列の完備辞書を効率的に表現できる。
【0019】
続いて、1と0との両方が連続しているビット列の完備辞書の圧縮手法について説明する。このようなビット列の例としては、「0000111100001111」のようなビット列が挙げられる。疎なビット列は0が長く連続するビット列であるが、このビット列においては、1も長く連続しており、この点で異なっている。また、本明細書では、1が連続している領域のことを「ラン(run)」と表記することとする。例えば、上記のビット列の例では、2つのランが含まれている。また、1と0とが連続するビット列の完備辞書は、ランレングス圧縮を用いて効率的に表現することができる。
【0020】
具体的には、非特許文献2は、このような1と0とが連続するビット列をランレングス圧縮することによって完備辞書を実現する手法を開示している(「3.1 Run-Length Encoded Wavelet Tree」参照)。
【0021】
なお、非特許文献2では、1が連続する領域は「1ビット・ラン(1-bit run)」と表記され、0が連続する領域は「0ビット・ラン(0-bit run)」と表記されているが、本明細書では、上述のように、特に指定のない限り、1が連続する領域を「ラン」と表記する。また、本明細書では、0が連続する領域のことは「空白」と表記する。従って、「0000111100001111」のようなビット列は、全て、ランと空白とが交互に並んでいるものと考えることができる。以下に、非特許文献2に開示されている手法について説明する。
【0022】
まず、1と0とが連続するビット列Bが与えられているとする。このとき、このビット列Bを、2つの疎なビット列B1とビット列Brlとによって表現することを考える。ビット列Bに含まれるランの数をbとする。また、ビット列B1は、全てのランの開始位置においてのみ、1になるような、疎なビット列であるとする。式で表すと、ビットB1は、下記の数2の通りとなる。なお、本明細書の数式では、B1をB
1と表現する。
【0023】
【数2】
【0024】
また、ビット列Bに含まれるランの数がbであるので、ビット列B1には、b個の1が含まれる。更に、ビット列Brlは、全てのランの長さを単進符号で表した結果をつなげた疎なビット列である。ビット列Brlにも、b個の1が含まれる。更に、ビット列B1とビット列Brlとは、どちらも疎なビット列なので、非特許文献1に記載されている疎なビット列の完備辞書を用いて、効率的に完備辞書を構築することができる。
【0025】
なお、非特許文献2では、非特許文献1に開示されている疎なビット列の完備辞書ではなく、非特許文献3に開示されている疎なビット列の完備辞書が用いられることになっている。但し、どちらの完備辞書も、rankとselectとを実現する点で共通であり、どちらの完備辞書が用いられても、動作に違いはない。以下においては、非特許文献1に記載されている疎なビット列の完備辞書を用いて説明する。
【0026】
また、ビット列Brlは、r番目のランの開始位置iにおけるrank1(B,i)の値を保存したものと見なすこともできる。即ち、ビット列Brlの中で、先頭から数えてr番目の1の位置は、r番目のランの開始位置iにおけるrank1(B,i)の値を表している。よって、下記の数3が成立する。なお、本明細書の数式では、BrlをB
rlと表現する。
【0027】
【数3】
【0028】
以上のように、ビット列Bは、ビット列B1とビット列Brlとによって表現することができるので、ビット列B上でのrank1、rank0、及びselect1の3種類の操作は、ビット列B1とビット列Brlの完備辞書を用いることで計算できる。
【0029】
具体的には、ビット列Bがビット列B1とビット列Brlとによって表現されている場合、rank1(B,i)は、以下のように計算できる。まず、r=rank1(B1,i)を計算する。rはビット列B上でiよりも前の位置で開始するランの数を表す。もしr=0であれば、[0,i)の範囲に1が存在しないことが確定するので、rank1(B,i)=0であり計算は終了する。
【0030】
一方、r>=1であれば、r番目のランの開始位置jについて考える。jは、j=select1(B1, r-1)で計算できる。求めるrank1(B,i)は、[0,j-1]の範囲における1の数と、[j,i)の範囲における1の数を足したものとなる。
【0031】
[0, j-1]の範囲における1の数は、以下のように計算できる。まず、r=1であれば、このランが最初のランであるので、[0,j-1]の範囲に存在する1の数は0である。r>1であれば、[0, j-1]の範囲における1の数は、r-1個のランの長さの合計であり、select1(Brl, r-1)で計算できる。次に、r番目のランの長さをkとする。このとき、kは、下記の数4によってで計算できる。また、[j,i)の範囲における1の数は、以下の数5によって計算できる。更に、rank0(B,i)は、下記の数6によって簡単に計算できる。
【0032】
【数4】
【0033】
【数5】
【0034】
【数6】
【0035】
また、ビット列Bがビット列B1とビット列Brlとによって表現されている場合、select1(B,i)は、以下の数7によって計算できる。但し、r = rank1(Brl,i+1)である。つまり、rは、先頭からランの長さを加算した場合に、ランの長さの合計がi+1となったときのランがr番目であることを表す。
【0036】
【数7】
【0037】
すなわち、求めるi+1番目の1はこのランの上にあることが分かる。また、上記数7において、select1(B1,r)は、このランの開始位置を表しており、i+1- select1(Brl,r)は、このランの中で何番目の1が、ビット列B全体の中でi+1番目の1であるかを表している。この値を合計して1を引けば、i+1番目の1の位置となる。
【0038】
ここで、ビット列Bが「001110011011」である場合の各操作の計算について具体的に説明する。このとき、ビット列B1は「0010000100101」、ビット列Brlは「10010101」となる。この場合において、i=8、つまり、rank1(B,8)を求めたいとする。
【0039】
位置iよりも前の位置から始まるランの数は、r=rank1(B1,8)=2である。2番目のランの開始位置はj=select1(B1,2-1)=7である。このとき、[0,j-1]の範囲における1の数は1個のランの長さの合計であり、select1(Brl,1)=3で計算できる。次に、2番目のランの長さをkとすると、上記数4において、r=2となるので、k=select1(Brl,2)-select1(Brl,2-1)=5-3=2となる。また、i-j= 8-7= 1<kであるので、[i,j)の範囲には1がi - j= 1個存在することが分かる。従って、求める答えは、rank1(B,8)=3+1=4となる。
【0040】
また、もうひとつの例として、i=10、つまり、rank1(B,10)を求める場合についても説明する。この場合も、k=2となるが、上記の例とは異なり、i-j=10-7=3>kが成立する。従って、求める答えは、rank1(B,10)=3+2=5となる。
【0041】
また、上記の例において、i=4、つまりselect1(B,4)を求めたいとする。この場合、位置iよりも前の位置から始まるランの数は、r=rank1(Brl,4+1)=2である。従って、求める位置は2番目のランの上にあることが分かる。このランの開始位置は、select1(B1,2-1)=7である。更に、求めるi+1番目の1は、4+1-select1(Brl,2-1)=4+1-3=2より、このランの中で2番目の1である。7+2-1=8より、求めるi+1番目の1はB[8]にあったことが分かる。
【0042】
以上のように、疎なビット列によって完備辞書を表現することができる。ここで、ビット列Bの完備辞書のサイズを考える。ビット列Bの完備辞書のサイズは、ビット列B1とビット列Brlとのサイズの和である。また、疎なビット列の完備辞書のサイズは、ビット列の長さをn、含まれる1の数をmとして、m log(n/m)+2m+o(m)ビットとなる。
【0043】
従って、この式をB1とBrlに当てはめると、ビット列に含まれるランの数をbとした場合、ビット列B1のサイズは、長さnでb個の1を含むので、b log(n/b)+2b +o(b)ビットとなる。同様に、ビット列Brlは、長さmでb個の1を含むので、b log(m/b)+2b+o(b)ビットとなる。従って、この2つを合計することで、ビット列Bの完備辞書のサイズが求められる。つまり、ビット列Bの完備辞書のサイズは、b (log(n/b)+log(m/b) +4)+o(b)ビットとなる。
【発明を実施するための形態】
【0057】
(発明の実施の形態の情報処理装置におけるデータ処理)
最初に、本発明の概要について説明する。本明細書では、a番目のランの開始位置sa におけるrank1(B, sa)の値を、ランのrank1と表記し、rank0(B, sa)の値をランのrank0と表記する。
【0058】
まず、全てのランについて、そのランの<開始位置、rank1、rank0>の3つの値が記憶されているとき、その3つの値さえあれば元のビット列Bを復元できるので、元のビット列Bを復元するのに十分な情報が得られることを示す。従って、以下の定理が成立する。
【0059】
定理:
ビット列B上の、任意のa番目のランについて、a番目のランの開始位置をsa、a+1番目のランの開始位置をsa+1とおく。このとき、sa、rank0(B, sa)、sa+1、rank1(B, sa+1)の4つの値さえ分かれば、B[sa , sa+1)の範囲の全てのビットについて1か0かを特定できる。
【0060】
(証明)
a番目のランが終了して0になる位置をeaとおく。このとき、ランの定義から、B[sa, ea)の範囲は全て1であり、B[ea , sa+1)の範囲は全て0である。このとき、eaの値は以下の数8によって計算できる。なお、本明細書の数式では、eaをe
aと表現する。
【0062】
また、上記の証明では、次の事実が用いられている。即ち、[sa , ea)の範囲には1しか存在しないため、rank0(B,ea)=rank0(B,sa)が成り立つ。同様に、[ea, sa+1)の範囲には0しか存在しないため、rank1(B,ea)=rank1(B,sa+1)が成り立つ。eaが具体的に計算できたので、B[sa, sa+1)のビットが全て判明する。(証明終わり)
【0063】
上述の定理によれば、連続する2つのランについて<開始位置、rank1、rank0>の値が分かれば、その2つのランの開始位置に挟まれた領域も完全に復元できることが分かる。
これを全てのランの間に適用すれば、全てのランについて、<開始位置、rank1、rank0>の3つの値が記憶されているとき、その3つの値さえあれば元のビット列Bを復元できる。
【0064】
ここで、本発明の実施の形態では、さらに、<開始位置、rank1、rank0>の3つの値のうち、2つの値さえわかっていれば、残り1つの値を動的に計算することができることに注目する。任意の開始位置iについて、以下の数9に示す関係が常に成り立つためである。
【0066】
これにより、全てのランについて、<開始位置、rank1、rank0>の3つの値のうち、2つの値さえわかっていれば、元のビット列Bを復元できることが分かる。
【0067】
このような視点に立って考えると、非特許文献2に開示された方法は、全てのランについて<開始位置、rank1>の2種類の値を常に記憶している場合に相当する。従って、非特許文献2に開示された方法では、rank1のビット列だけが保持されているので、select1を高速に計算することはできる。しかし、非特許文献2に開示された方法では、rank0のビット列は保持されていないため、select0を高速に計算できないという問題が発生する。
【0068】
なお、非特許文献2に記載の方法を、単純に、<開始位置、rank1、rank0>の3種類の値の全てを記憶するように拡張することも考えられる。しかし、この場合は、上述の問題の解決は可能となるが、「発明が解決しようする課題」の欄でも述べたように、必要なデータのサイズが、<開始位置、rank1>の2種類の値を記憶している倍に比べて、約1.5倍に増大してしまう。
【0069】
このため、本発明の実施の形態における情報処理装置は、非特許文献2に開示された方法のように、常に同じ2種類の値を記憶するのではなく、それぞれのランについて、異なる2種類の値を選択し、選択した2種類の値を記憶してもよい。
【0070】
すなわち、本発明では、全てのランのそれぞれに関して、<開始位置、rank1、rank0>の3つの値のうち2つの値だけを選び、その値を記憶してもよい。さらに、各位置について、記憶する2つの値を変更してもよい。たとえば、あるランについては、<開始位置、rank1>の2つの値だけを記憶し、他のあるランについては<開始位置、rank0>の2つの値を記憶してもよい。これにより、あるランではrank0の値が記憶されておらず、また、あるランではrank1の値が記憶されていない状態になる。これはすなわち、全てのランについてrank1やrank0を記憶するのではなく、一部のランについてサンプリングして記憶していることを表す。
【0071】
この場合、<開始位置、rank1、rank0>の3つの値のうち2つの値だけしか記憶されていないので、情報処理装置は、<開始位置、rank1、rank0>の3つの値の全てを記憶する場合に比べて、必要なデータのサイズを約3分の2の大きさにでき、記憶領域を節約できる。上述したように、情報処理装置は、3つの値のうち残り1つの値を、他の2つの値から動的に計算できる。
【0072】
ランの開始位置を配列すると、全てのランについて単調増加する配列であり、同様にrank1とrank0も単調増加する配列となる。よって、疎なビット列の完備辞書によって効率的に開始位置やrank1やrank0を検索できる。
【0073】
非特許文献2に記載の方法に比べて、本発明の実施の形態が優れているのは、全ての開始位置についてrank1を記憶するのではなく、ランによって、時にはrank1、時にはrank0を記憶することである。これにより、情報処理装置は、ビット列全体の様々な場所におけるrank1とrank0の値をサンプリングしている状態になる。情報処理装置が、select1を計算するときには、このサンプリングされたrank1の値を検索することで、だいたいの位置のあたりをつけることができる。select0を計算するときは、サンプリングされたrank0の値を検索することで、だいたいの位置のあたりをつけることができる。だいたいの位置のあたりをつけた後、情報処理装置は、その周囲のランのrank1あるいはrank0の値を動的に計算して、正確な位置を求める。
【0074】
具体的には、情報処理装置が、select1(B,i)を計算するときは、まず初めに、rank1の値が記憶されているランの中から、iに近いrank1の値を持つランを特定する。次に、情報処理装置は、このランを手がかりとして、このランの周囲に存在する、rank1の値が記憶されていないランについて、そのランまでのrank1の値を動的に計算する。そのようなランのrank1の値は、残り2つの値、すなわちランの開始位置とrank0の値から動的に計算される。こうして、情報処理装置は、周囲のランのrank1の値を復元することで、実際にi番目に1が出現する位置を計算することができる。
【0075】
また、情報処理装置が、select0(B,i)を計算するときは、逆に、rank0の値が記憶されているランの中から、iに近いrank0の値を持つランを特定し、その周囲に存在する、rank0の値が記憶されていないランについて、rank0の値を動的に計算すればよい。
【0076】
なお、3種類のうちどの2種類を選択して記憶するかは、特には限定されないが、選択の仕方には様々な方法が存在する。たとえば、情報処理装置は、ランごとに3種類の値をローテーションで記憶してもよい。すなわち、1番目のランでは開始位置以外の2つを記憶し、2番目のランではrank1以外の2つを記憶し、3番目のランではrank0以外の2つを記憶し、4番目のランでは、再び戻って、開始位置以外の2つを記憶する、といった方法が考えられる。
【0077】
また、偶数番目のランについて<開始位置、rank1>の2つの値を記憶し、奇数番目のランについて<開始位置、rank0>の2つの値を保持する方法も挙げられる。この場合、情報処理装置は、偶数番目のランの開始位置におけるrank0の値と、奇数番目のランの開始位置におけるrank1の値は保持されないが、動的に計算できる。
【0078】
(実施の形態)
以下、本発明の実施の形態における、データ構造、情報処理装置、情報処理方法、及びプログラムについて、
図1〜
図6を参照しながら説明する。
【0079】
[装置構成]
最初に、本実施の形態における情報処理装置の構成について説明する。
図1は、本発明の実施の形態における情報処理装置の概略構成を示すブロック図である。
【0080】
図1に示すように、本実施の形態における情報処理装置100は、データ構造11を記憶した記憶部10を備えている。データ構造11は、第1の値と第2の値とで構成されたビット列を表現するためのデータ構造であり、第1のデータ12と、第2のデータ13と、第3のデータ14とを有している。
【0081】
また、これのデータのうち、第1のデータは、ビット列上で、第1の値又は第2の値が1個以上連続する連続区間の全部又は一部の位置を特定するデータである。また、第2のデータは、連続区間の一部について、ビット列上で、ビット列の先頭から当該連続区間までに出現した第1の値の出現数を特定するデータである。第3のデータは、連続区間の一部について、ビット列上で、ビット列の先頭から当該連続区間までに出現した第2の値の出現数を特定するデータである。
【0082】
ここで、本実施の形態では、第1の値が「1」、第2の値が「0」、第1のデータが位置を特定する連続区間が「1」の連続区間であるとする。この場合、第1のデータは、ランの開始位置を特定するデータ(以下「連続区間位置データ」と表記する。)である。また、第2のデータは、対応する連続区間までの「1」の出現数、すなわちrank1の値を特定するデータ(以下「rank1データ」と表記する。)である。更に、第3のデータは、対応する連続区間までの「0」の出現数、すなわちrank0の値を特定するデータ(以下「rank0データ」と表記する。)である。
【0083】
つまり、本実施の形態では、記憶部10において、連続区間の全部又は一部について、<開始位置、rank1、rank0>の3つの値のうちいずれかが、格納されている。したがって、対象となるビット列について2種類のselect操作が可能となる。また、全ての連続区間において、3つの値を全て格納しておく必要がないため、完備辞書(データ構造11)のサイズの増大が抑制される。
【0084】
続いて、
図2を用いて、本実施の形態における情報処理装置100の構成を更に具体的に説明する。
図2は、本発明の実施の形態における情報処理装置100の構成を具体的に示すブロック図である。
【0085】
図2に示すように、本実施の形態における情報処理装置100は、データ構造11を格納する上述の記憶部10に加えて、計算部20と、入力受付部30と、出力部40とを備えている。本実施の形態では、情報処理装置100は、例えば、コンピュータに後述するプログラムを導入することによって構築される。この場合、情報処理装置100は、コンピュータを構成するオペレーティングシステムの一部として機能することができる。
【0086】
このうち、入力受付部30は、外部からの入力を受け付け、これを計算部20に出力する。出力部40は、計算部20による計算結果を外部に出力する。計算部20は、第1のセレクト計算部21と、第2のセレクト計算部22と、第1のランク計算部23と、第2のランク計算部24とを備えている。
【0087】
計算部20において、第1のセレクト計算部21は、自然数が入力されたときに、ビット列上の位置であって、先頭から当該位置までに含まれる「1(第1の値)」の個数が自然数と等しくなる第1のセレクト位置を特定する。また、第1のセレクト計算部21は、第1のセレクト位置を連続区間位置データ、rank1データ、及びrank0データを用いて、特定する。即ち、第1のセレクト計算部21は、ビット列Bに対してselect1(B,i)を実行する。
【0088】
また、第2のセレクト計算部22は、自然数が入力されたときに、ビット列上の位置であって、先頭から当該位置までに含まれる「0(第2の値)」の個数が自然数と等しくなる第2のセレクト位置を、連続区間位置データ、rank1データ、及びrank0データを用いて、特定する。即ち、第2のセレクト計算部21は、ビット列Bに対してselect0(B,i)を実行する。
【0089】
また、第1のランク計算部23は、ビット列上の位置が指定されたときに、連続区間位置データ、rank1データ、及びrank0データを用いて、指定された位置までに出現した「1(第1の値)」の出現数を特定する。即ち、第1のランク計算部23は、ビット列Bに対してrank1(B,i)を実行する。更に、第2のランク計算部24は、ビット列上の位置が指定されたときに、連続区間位置データ、rank1データ、及びrank0データを用いて、指定された位置までに出現した「0(第2の値)」の出現数を特定する。即ち、第2のランク計算部24は、ビット列Bに対してrank0(B,i)を実行する。
【0090】
ここで、
図3及び
図4を用いて、本実施の形態で用いられるデータ構造について更に具体的に説明する。
図3は、対象となるビット列とそれから求められる各種値との一例を示す図である。
図4は、
図3に示すビット列を表現するためのデータ構造の一例を示す図である。
【0091】
図3の例では、データであるビット列Bは[001110011011]であり、1について3つの連続区間(ラン)を有している。また、各ランの開始位置は、2,7,10となっている。「開始位置」を示す行では、該当する開始位置の箇所に、出現順位が記載されている。また、「pos1」は、位置を表している。なお、本明細書では、ビット列Bの配列の添字は0から開始されるが、ランの序列は1番目からカウントされるので、0番目のランは存在しないものとする。
【0092】
また、
図3において、「rank1」は、ビット列Bにおける各位置での先頭からの「1」の出現数、即ち、rank1の値を示している。「rank0」は、ビット列Bにおける各位置での先頭からの「0」の出現数、すなわちrank0の値を示している。「select1」は、その位置がselect1(B,i)の結果として返されるような、入力値iを示している。「select0」は、その位置がselect0(B,i)の結果として返されるような、入力値iを示している。
【0093】
そして、
図4に示すように、本実施の形態では、連続区間位置データは、
図3における「開始位置」のデータをビット列化して得られたデータである。また、rank1データは、
図3における開始位置の「rank1」のデータをビット列化して得られたデータである。rank0データは、
図3における開始位置の「rank0」のデータをビット列化して得られたデータである。なお、連続区間位置データを構成するビット列を「B1」、rank1データを構成するビット列を「Br1」、rank0データを構成するビット列を「Br0」と表記する。
【0094】
但し、情報処理装置100は、「rank1」及び「rank0」について、全ての連続区間の開始位置についてビット列化してしまうと、データ構造11のデータ量が増大してしまう。このため、本実施の形態では、データ構造11は、各連続区間について、開始位置と、rank1と、rank0との3つの値のうち、少なくとも2つの値が、連続区間位置データ、rank1データ、rank0データによって特定されるように構築されている。また、このとき、特定される少なくとも2つの値は、連続区間の位置(開始位置)によって変化するようになっている。
【0095】
具体的には、
図4の例における連続区間位置データは、ビット列B上で、「1」が1個以上連続する連続区間の全部の位置を特定する。また、rank1データが「1」の出現数を特定した連続区間は、偶数番目に出現した連続区間と一致する。一方、rank0データが「0」の出現数を特定した連続区間は、奇数番目に出現した連続区間とする。
【0096】
なお、本実施の形態において、データ構造11は、
図4に示す例に限定されることはない。例えば、データ構造は、1番目の連続区間では、rank1とrank0とを特定し、2番目の連続区間では、開始位置とrank0とを特定し、三番目の連続区間では、開始位置とrank1とを特定し、以後、この繰り返しが行われるように構築されていても良い。
【0097】
また、データ構造11が
図4に示すものである場合は、第1のセレクト計算部21及び第2のセレクト計算部22は、次のように計算を行う。つまり、第1のセレクト計算部21は、まず、rank1データが特定する「1」の出現数に基づいて、rank1データにおいて「1」の出現数が特定されており、且つ、特定の対象となるselect1が存在又は近接する、連続区間を推定する。
【0098】
次に、第1のセレクト計算部21は、推定した連続区間に近接し、且つ、rank1データにおいて「1」の出現数が特定されていない連続区間について、連続区間位置データ及びrank0データに基づいて、「1」の出現数を特定する。そして、第1のセレクト計算部21は、特定した「1」の出現数を用いて、select1を特定する。
【0099】
また、第2のセレクト計算部22は、連続区間について、まず、rank0データが特定する「0」の出現数に基づいて、rank0データにおいて「0」の出現数が特定されており、且つ、特定の対象となるselect0が存在又は近接する、連続区間を推定する。
【0100】
次に、第2のセレクト計算部22は、推定した連続区間に近接し、且つ、rank0データにおいて「0」の出現数が特定されていない連続区間について、連続区間位置データ及びrank1データに基づいて、「0」の出現数を特定する。そして、第2のセレクト計算部22は、特定した「0」の出現数を用いて、select0を特定する。
【0101】
また、本実施の形態では、データ構造11は、連続区間位置データが特定する位置、rank1データが特定する「1」の出現数、rank0データが特定する「0」の出現数、それぞれを、単調増加する数列とみなすことによって圧縮されているのが良い。この場合、データ構造11は、圧縮された状態で記憶部10に記憶される。
【0102】
[装置動作]
次に、本発明の実施の形態における情報処理装置100の動作について
図5を用いて説明する。
図5は、本発明の実施の形態における情報処理装置の動作を示すフロー図である。以下の説明においては、適宜
図1を参酌する。また、本実施の形態では、情報処理装置100を動作させることによって、情報処理方法が実施される。よって、本実施の形態における情報処理方法の説明は、以下の情報処理装置100の動作説明に代える。
【0103】
図5に示すように、まず、入力受付部30は、外部からの自然数の入力と要求される操作の入力とを受付け(ステップA1)、受付けた内容を計算部20に出力する。
【0104】
次に、計算部20は、要求された操作がselect1であるかどうかを判定する(ステップA2)。ステップA2の判定の結果、要求された操作がselect1である場合は、第1のセレクト計算部21が、記憶部10から、連続区間位置データ11、rank1データ12、及びrank0データ13を取得する。そして、第1のセレクト計算部21は、これらを用いてステップA1で受付けられた自然数についてselect1を計算する(ステップA3)。
【0105】
ステップA2の判定の結果、要求された操作がselect1でない場合は、計算部20は、要求された操作がselect0であるかどうかを判定する(ステップA4)。ステップA4の判定の結果、要求された操作がselect0である場合は、第2のセレクト計算部22が、記憶部10から、連続区間位置データ11、rank1データ12、及びrank0データ13を取得する。そして、第2のセレクト計算部22は、これらを用いてステップA1で受付けられた自然数についてselect0を計算する(ステップA6)。
【0106】
また、ステップA4の判定の結果、要求された操作がselect0でない場合は、計算部20は、要求された操作がrank1であるかどうかを判定する(ステップA5)。ステップA5の判定の結果、要求された操作がrank1である場合は、第1のランク計算部23が、記憶部10から、連続区間位置データ11、rank1データ12、及びrank0データ13を取得する。そして、第1のランク計算部23は、これらを用いてステップA1で受付けられた自然数についてrank1を計算する(ステップA7)。
【0107】
一方、ステップA5の判定の結果、要求された操作がrank1でない場合は、第2のランク計算部24が、記憶部10から、連続区間位置データ11、rank1データ12、及びrank0データ13を取得する。そして、第2のランク計算部24は、これらを用いてステップA1で受付けられた自然数についてrank0を計算する(ステップA8)。
【0108】
上述のステップA3、A6、A7、又はA8が実行されると、出力部40は、計算結果を受け取り、計算結果を外部に出力する(ステップA9)。このように、ステップA1〜A9の実行により、データ構造11を用いて、select1、select0、rank1、rank0の操作が可能となる。
【0109】
[実施の形態による効果]
続いて、本実施の形態による効果について説明する。
図4に示したように、本実施の形態では、ビット列Bに対して、3つの疎なビット列B1、Br1、Br0が、データ構造11として用意される。ビット列B1はランの開始位置においてのみ1となる疎なビット列である。
ビット列Br1は、偶数番目のランの開始位置におけるrank1の値を記憶するビット列である。すなわち、偶数番目のランの開始位置iについて、Br1 [rank1(B,i)] = 1としてセットし、それ以外の要素は0とする。このビット列の長さは、ビット列Bに含まれる「1」の個数mに等しい。また、このビット列には、b/2個の「1」が含まれている。
【0110】
同様に、Br0を定義する。すなわち、奇数番目のランの開始位置iについて、Br0 [rank0(B,i)] = 1としてセットし、それ以外の要素は0とする。このビット列の長さは、Bに含まれる「0」の数(n-m)に等しい。また、このビット列には、b/2個の1が含まれている。
【0111】
そして、本実施の形態において、データ構造11のサイズ、すなわち、完備辞書のサイズは、3つの疎なビット列B1、ビット列Br1、及びビット列Br0それぞれの完備辞書のサイズの合計となる。具体的には、ビット列B1の完備辞書のサイズは、長さnでb個の1を含むため、b log(n/b)+2b +o(b)ビットである。また、ビット列Br1の完備辞書のサイズは、長さmでb/2個の1を含むため、(b/2) log(2m/b) + 2(b/2) + o(b)ビットである。ビット列Br0の完備辞書のサイズは、長さ(n-m)でb/2個の1を含むため、(b/2) log(2(n-m)/b) + 2(b/2) + o(b)ビットである。従って、これらを合計すると、完備辞書(データ構造11)の合計のサイズSは、下記の数10に示す通りとなる。
【0113】
ここで、log(n/b)と、log(2m/b)と、log(2(n-m)/b)とは、それぞれ略等しい大きさであると見なすことができる。たとえば、m=n/2の場合、すなわち、長さnのビット列のうち、半分が「1」であり、半分が「0」であるような場合はこれらの数はlog(n/b)に等しくなる。これらの値をCとおくと、本実施の形態における完備辞書のサイズは、2b(C+2)+o(b)ビットとなる。これはすなわち、select1だけをサポートする非特許文献2の完備辞書とほぼ同じサイズでありながら、select1とselect0の両方の操作をサポートできることを示している。さらに言えば、これは、本実施の形態における完備辞書のサイズは、select1とselect0の両方をサポートするようにした非特許文献2の完備辞書のサイズの約(2/3)となることを示している。すなわち、本実施の形態によれば、完備辞書に対してselect1とselect0の両方の操作をサポートする機能を付与しつつ、その大きさを従来の約(2/3)倍に縮小することができる。
【0114】
[変形例]
上述した例では、第1の値が「1」、第2の値が「0」、第1のデータが位置を特定する連続区間が「1」の連続区間であるが、本実施の形態は、この例に限定されるものではない。ビット列の1と0とは交換可能であるため、1と0とを反転させ、第1の値が「0」、第2の値が「1」、第1のデータが位置を特定する連続区間が「0」の連続区間であっても良い。この場合であっても、上述した効果と全く同じ効果を得ることができる。
【0115】
また、
図4の例では、連続区間位置データは、連続区間の開始位置を保持している。しかし、本実施の形態では、前後を入れ替えることができ、連続区間位置データは、連続区間の開始位置の代わりに終了位置を保持していても良い。この場合であっても、同様の効果が得られる。更に、
図4の例では、偶数番目のランについてrank1が保持され、奇数番目のランについてrank0が保持されているが、本実施の形態では、この奇数と偶数の関係が入れ替えられていても良く、この場合でも、同様の効果が得られる。
【0116】
[プログラム]
本実施の形態におけるプログラムは、コンピュータに、
図5に示すステップA1〜A9を実行させるプログラムであれば良い。このプログラムをコンピュータにインストールし、実行することによって、本実施の形態における情報処理装置100と情報処理方法とを実現することができる。この場合、コンピュータのCPU(Central Processing Unit)は、入力受付部30、計算部20、及び出力部40として機能し、処理を行なう。また、記憶部10は、コンピュータに備えられた、メモリ、ハードディスク等の記憶装置に、これらを構成するデータファイルを格納することによって実現されている。
【0117】
ここで、本実施の形態におけるプログラムを実行することによって、情報処理装置100を実現するコンピュータについて
図6を用いて説明する。
図6は、本発明の実施の形態における情報処理装置を実現するコンピュータの一例を示すブロック図である。
【0118】
図6に示すように、コンピュータ110は、CPU111と、メインメモリ112と、記憶装置113と、入力インターフェイス114と、表示コントローラ115と、データリーダ/ライタ116と、通信インターフェイス117とを備える。これらの各部は、バス121を介して、互いにデータ通信可能に接続される。
【0119】
CPU111は、記憶装置113に格納された、本実施の形態におけるプログラム(コード)をメインメモリ112に展開し、これらを所定順序で実行することにより、各種の演算を実施する。メインメモリ112は、典型的には、DRAM(Dynamic Random Access Memory)等の揮発性の記憶装置である。また、本実施の形態におけるプログラムは、コンピュータ読み取り可能な記録媒体120に格納された状態で提供される。なお、本実施の形態におけるプログラムは、通信インターフェイス117を介して接続されたインターネット上で流通するものであっても良い。
【0120】
また、記憶装置113の具体例としては、ハードディスクの他、フラッシュメモリ等の半導体記憶装置が挙げられる。入力インターフェイス114は、CPU111と、キーボード及びマウスといった入力機器118との間のデータ伝送を仲介する。表示コントローラ115は、ディスプレイ装置119と接続され、ディスプレイ装置119での表示を制御する。
【0121】
データリーダ/ライタ116は、CPU111と記録媒体120との間のデータ伝送を仲介し、記録媒体120からのプログラムの読み出し、及びコンピュータ110における処理結果の記録媒体120への書き込みを実行する。通信インターフェイス117は、CPU111と、他のコンピュータとの間のデータ伝送を仲介する。
【0122】
また、記録媒体120の具体例としては、CF(Compact Flash)及びSD(Secure Digital)等の汎用的な半導体記憶デバイス、フレキシブルディスク(Flexible Disk)等の磁気記憶媒体、又はCD−ROM(Compact Disk Read Only Memory)などの光学記憶媒体が挙げられる。
【実施例1】
【0123】
以下に、
図1〜
図6に示した本実施の形態の情報処理装置の具体例について説明する。
その際、本実施の形態におけるデータ構造(完備辞書)が、完備辞書として利用可能であること、すなわちaccess、rank、selectの操作が行えることを中心に説明する。
【0124】
以下の説明では、計算を簡単にするための工夫として、長さnのビット配列Bが与えられたとき、n+1番目の要素B[n]から仮想的なランが始まっているものと見なして、B[n]がランの開始位置として記録される。これは、後述するrank及びselectの計算処理において、例外処理を行わないようにするためである。
【0125】
また、後述する計算では、a番目のランとa+1番目のランの開始位置を計算する処理が何度も出てくる。ここで、B[n]から新しいランが始まっていると見なして登録しておくことで、a+1番目のランが存在しない場合の例外処理を行うことが回避される。なお、このような仮想的なランを想定することで、ランの数は1つ増える。この増加した仮想的なランは、配列全体からみると無視できるほど小さいため、完備辞書のサイズの計算からは除外される。
【0126】
ここで、
図3に示したビット列Bを想定する。
図3に示したビット列Bは、長さ12のビット列のうち、7個の1と5個の0とで構成されている。このビット列Bにおけるランの開始位置は、B[2],B[7],B[10],B[12]の4箇所である。なお、B[12]から始まるランは、実際のビット列Bには存在しない仮想上のランである。
【0127】
ビット列Bにおいて、access(B,i)とrank1(B,i)とは、計算部20によって、以下のように、ほぼ同様の操作で計算される。まず、a= rank1(B1, i+1)を用いて、B[0,i]に含まれるランの開始位置の数aが得られる(
図4参照)。
【0128】
a=0であった場合は、access(B,i)とrank1(B,i)とはともに0であるので、計算部20の計算は終了する。一方、a>0であった場合、計算部20は、a番目のランに着目する。引数として与えられた位置iは、a番目のランの上にあるか、a番目のランとa+1番目のランとの間にあるかのどちらかである。位置iとこれらのランとの相対的な位置関係が求まれば、計算部20はaccessとrank1の値を計算できる。
【0129】
また、a番目のランの開始位置をsa、a番目のランが終了して0になる位置をea、a+1番目のランの開始位置をsa+1とする。このとき、sa≦i<sa+1およびsa<ea≦sa+1が常に成り立つ。B[sa,ea)の範囲は全て1であり、B[ea,sa+1)の範囲は全て0である。
【0130】
そして、上記の場合において、i<eaであれば、位置iはa番目のランの上にあることにある。すなわち、access(B,i)=B[i]=1である。一方ea≦iであれば、位置iは、a番目のランとa+1番目のランとの間に位置する。すなわち、access(B,i)=B[i]=0である。
【0131】
ここで、aが奇数の場合とaが偶数の場合とに場合分けする。aが奇数なら、以下の数11によって、eaを効率的に計算できる。なお、本明細書の数式では、sa をs
a と、sa+1をs
a+1と、Br0をB
r0と、Br1をB
r1と表現する。
【0132】
【数11】
【0133】
また、上記の数11では、以下の事実が用いられている。すなわち、[sa , ea)の範囲には1しかないため、rank0(B,ea)=rank0(B,sa)が成り立つ。同様に、[ea, sa+1)の範囲には0しかないため、rank1(B,ea)=rank1(B,sa+1)が成り立つ。また、saにおけるrank0の値はBr0における「(a-1)/2+1」番目の1の位置として記録される。sa+1におけるrank1の値はBr1における「(a-1)/2+1」番目の1の位置として記録される。よって、それぞれの完備辞書でselect1を計算した結果の和を取れば、eaの値が計算される。
【0134】
こうしてeaの値が求まったので、あとは前述の通り、iの値と比較することで、access(B,i)の値が計算される。
【0135】
rank1(B,i)を計算するには、計算部20は、同じように場合分けをすればよい。i< eaであれば、以下の数12によって、求める答えを計算できる。
【0136】
【数12】
【0137】
上記数12によって答えが計算できるのは、[sa,i)の間は、全て1であることが保証されているからである。rank0(B,sa)は、eaを計算するときに計算済みであるため、2つの値を引き算するだけでよい。
【0138】
一方、 ea <=iであれば、以下の数13によって、求める答えを計算できる。
【0139】
【数13】
【0140】
上記数13によって答えが計算できるのは、[sa,ea)の間は全て1であるのに対して、[ea,i)の間は全て0であるからである。なお、rank1(B,sa+1)の値はeaを計算するときに計算済みである。
【0141】
以上により、aが奇数の場合は、access(B,i)とrank1(B,i)が計算できることが示された。
【0142】
ここで、
図3に示したビット列Bを用いて、aが奇数になる場合の具体的な計算例を以下に示す。また、この計算例では、i=5とする。すなわち、access(B,5)またはrank1(B,5)を求めたいとする。
【0143】
この場合、a= rank1(B1,5+1)=1であり、奇数である。従って、a=1番目のランと、a+1=2番目のランに注目する。従って、eaは下記の数14に示す値となる。
【0144】
【数14】
【0145】
上記の数15より、ea ≦iが成り立つことが分かるので、位置iは、1番目のランと2番目のランとの間となる。すなわち、access(B,i)=B[i]=0である。更に、rank1は下記の数15に示す値となる。
【0146】
【数15】
【0147】
続いて、aが偶数の場合の計算方法を以下に説明する。まず、位置saと位置sa+1との値を求める。sa=select1(B1,a-1)、sa+1=select1(B1,a)となる。ここで、ビット列B1としては、非特許文献1に記載された疎なビット列の完備辞書が用いられているため、aの値は、saとsa+1の値を探索することなく、計算できることに注意する。何故なら、この完備辞書においては、a個目の要素とa+1個目の要素とは記憶領域上で隣接して記憶されているため、再度探索する必要がないからである。このとき、もし、sa=iであった場合、iがランの開始位置であり、B[i]=1である、と分かるので、これ以上計算しなくともaccess(B,i)=1であると分かる。
【0148】
saとsa+1の値を具体的に求めた後は、以下の数16によって、eaの値が具体的に計算される。
【0149】
【数16】
【0150】
こうして、eaの値が求まったので、後は、計算部20は、上述の通り、eaの値とiの値とを比較することで、access(B,i)の値を計算する。
【0151】
また、rank1(B,i)の計算は、aが奇数の場合の計算と同様に行われる。すなわち、i<eaであれば、rank1(B,i)=i-rank0(B,sa)で求める答えが計算できる。一方、ea≦iであれば、rank1(B,i)=rank1(B,sa+1)となる。
【0152】
以上のように、データ構造11を用いれば、計算部20は、accessとrank1とを計算することができる。実質的には、計算部20は、ビット列B1上でrank1を1回計算し、ビット列Br1上でselect1を1回計算し、ビット列Br0上でselect1を1回計算することになる。また、rank0(B,i)は、「i - rank1(B,i)」に等しいので、rank1の値から簡単に計算できる。
【0153】
ここで、
図3に示したビット列Bを用いて、aが偶数になる場合の具体的な計算例を以下に示す。また、この計算例では、i=9とする。すなわちaccess(B,9)又はrank1(B,9)を求めたいとする。
【0154】
この場合、a= rank1(B1,9+1)=2であり、偶数である。従って、a=2番目のランと、a+1=3番目のランに注目する。
【0155】
まず、位置saと位置sa+1の値を求める。sa=select1(B1,a-1)= select1(B1,1)=7、およびsa+1=select1(B1,a) = select1(B1,2)=10である。従って、eaは下記の数17に示す値となる。
【0156】
【数17】
【0157】
上記の数17より、ea≦iが成り立つので、access(B,i)=B[i]=0である。更に、rank1は下記の数18に示す値となる。
【0158】
【数18】
【0159】
続いて、ビット列Bにおけるselect1(B,i)の計算方法について、
図7を用いて以下に説明する。
図7は、本発明の実施例におけるselect1(B,i)の計算方法を概略的に説明する図である。まず、計算部20は、a=rank1(Br1,i+1)を求める。これは、偶数番目のランであって、そのランの開始位置におけるrank1の値がiを超えないランのなかで、その数が最大となるようなランが、(偶数番目のランのなかで数えて)何番目であるかを求めるためである。また、このようなランは、偶数番目のランの中では、a番目であるが、奇数番目と偶数番目と合わせた全体のランの中では、a*2番目である。
【0160】
ここで、
図7にも示す、(a*2)番目、(a*2+1)番目、(a*2+2)番目という3つのランに注目する。目的となるiは、(a*2)番目のラン、及び(a*2+1)番目のランのどちらかの上に存在する。どちらのランの上にあるかは、(a*2+1)番目のランの開始位置sa*2+1におけるrank1の値、すなわちb=rank1(B, sa*2+1)と、iとを比較すればよい。ただし、(a*2+1)番目のランの開始位置におけるrank1の値は、奇数番目なのでデータ構造11(完備辞書)には直接保存されていないので、計算部20は、位置とrank0の値から、bを算出する必要がある。bの値は、以下の数19を用いることで計算できる。また、このとき、下記の数19における、(a*2+1)番目のランの開始位置におけるrank0の値c(=rank0(B, sa*2+1))が保持される。
【0161】
【数19】
【0162】
上記数19によって、bが求まるので、計算部20は、iとbとを比較する。比較の結果、i<bであれば、求める位置はa*2番目のランの上に存在する。このランの開始位置は、sa*2=select1(B1, a*2-1)で求められる。また、a*2番目のラン上の位置におけるrank1の値はd=rank1(B,sa*2)=select1(Br1, a-1 )で計算される。なお、初めにa=rank1(Br1,i+1)が計算された段階で、a番目の要素が見つけられているので、計算部20は、新たに探索をすることなく、この値を計算できる。求める答えは、sa*2+(i-d)である。
【0163】
一方、b<=iであれば、求める位置は(a*2+1)番目のランの上に存在する。従って、求める答えは、i+cである。何故なら、答えとなる位置よりも前には、i個の1とc個の0しか存在しないため、その位置はi+cとなるからである。
【0164】
以上のように、計算部20は、データ構造11を用いて、select1の答えを計算することができる。ところで、最初にaの値を計算するときに、a=0となることがあるが、この場合でも全く同じ計算で良い。この場合、(a*2)番目のランは存在しないため、iは必ず(a*2+1)番目のランの上に存在する。このとき上記のbは必ず0になるため、i<bとなることはない。
【0165】
また、本実施例では、計算部20が、一見何度も同じデータ構造11を呼び出しているように見えるが、一度発見した要素に隣接する要素を参照しているだけであるため、計算部20によるデータ構造11での探索は1回で済んでいる。すなわち、ビット列Br1でのrank1、ビット列B1でのselect1、ビット列Br0でのselect1の計3回である。
【0166】
ここで、
図3に示したビット列Bを用いて、i=4であるときの、select1(B,4)を求める計算例について説明する。この場合、a=rank1(Br1,4+1)=1となるので、a*2=2、a*2+1=3となる。従って、求める位置は、2番目のランか3番目のランの上に存在することが分かる。ここで、計算部20によって、3番目のランの開始位置におけるrank1の値bを計算すると、下記数20に示す通りとなる。
【0167】
【数20】
【0168】
上記数20においては、(a*2+1)番目のランの開始位置におけるrank0の値c(=rank0(B,sa*2+1) =5)が保持される。そして、i=4とb=5とが比較され、i<bが成り立つため、計算部20は、求める位置はa*2番目のランの上に存在すると判断する。また、このランの開始位置は、sa*2=select1(B1,a*2-1)=7である。この位置におけるrank1の値はd=rank1(B,sa*2)=select1(Br1, a-1 )=3である。従って、求める答えは、sa*2+(i-d) =7+(4-3)=8となる。もしi=6であるとすると、bの値までは同じだが、b≦iが成り立つため、答えは、i+c=6+5=11となる。
【0169】
また、計算部20は、select0(B,i)を、select1(B,i)と同様にして求めることができる。但し、偶数と奇数との関係、及びランと空白との関係が逆転する。まず、計算部20は、a=rank1(Br0,i+1)を求める。これは、奇数番目のランであって、そのランの開始位置におけるrank0の値がiを超えないランのなかで、その数が最大となるようなランが、(奇数番目のランのなかで数えて)何番目であるかを求めるためである。
【0170】
計算の結果、a=0であった場合、探しているi+1番目の0は、1番目のランよりも前にあることが分かる。これはB[0,i]の範囲が全て0であることを示している。よって、求める答えはselect0(B,i)=iである。以下では、a>0となる場合を考える。
【0171】
さて、この奇数番目のランの中ではa番目のランは、奇数番目と偶数番目と合わせた全体のランの中では、(a*2-1)番目である。従って、(a*2-1)番目、(a*2)番目、(a*2+1)番目という3つのランに注目する。
【0172】
目的となるiは、(a*2-1)番目のランと(a*2)番目のランとに挟まれた空白か、(a*2)番目のランと(a*2+1)番目のランとに挟まれた空白の、どちらかの上に存在する。どちらの空白の上にあるかは、(a*2)番目のランの開始位置sa*2におけるrank0の値、すなわちb=rank0(B,sa*2)とiとを比較すればよい。
【0173】
ただし、(a*2)番目のランの開始位置におけるrank0の値は、偶数番目なので完備辞書には直接保存されておらず、位置とrank1の値とから算出する必要がある。この値は、以下の数21を用いることで計算できる。
【0174】
【数21】
【0175】
上記数21においては、a*2番目のランの開始位置におけるrank1の値c(=rank1(B,sa*2))が保持される。そして、iとbとを比較し、i<bであれば、求める位置は(a*2-1)番目のランと(a*2)番目のランとに挟まれた空白に存在する。その場合、求める答えはi+cである。何故なら、求める位置より前には、i個の0とc個の1が存在するからである。
【0176】
一方、b<=iであれば、求める位置は(a*2)番目のランと(a*2+1)番目のランとに挟まれた空白に存在する。ここで、(a*2+1)番目のランの開始位置におけるrank1の値をdとおくと、dは、以下の数22を用いることで計算できる。
【0177】
【数22】
【0178】
求める答えは、i+dである。何故なら、求める位置より前には、i個の0とd個の1が存在するからである。
【0179】
ここで、
図3に示したビット列Bを用いて、i=2であるときの、select0(B,2)を求める計算例について説明する。この場合、a=rank1(Br0,2+1)=1となるので、a*2-1=1、a*2=2となる。従って、求める位置は、1番目のランと2番目のランとに挟まれた空白、又は2番目のランと3番目のランとに挟まれた空白、のどちらかの上に存在することが分かる。ここで、2番目のランの開始位置におけるrank0の値bを計算すると、下記数23に示す通りとなる。
【0180】
【数23】
【0181】
上記数23においては、a*2番目のランの開始位置におけるrank1の値c(=rank1(B,sa*2)=3)が保存される。そして、i=2とb=4とが比較され、i<bが成り立つため、計算部20は、求める位置はa*2-1番目のランとa*2番目のランとに挟まれた空白の上に存在すると判断する。結果、求める答えは、i+c=2+3=5である。
【0182】
また、i=4であった場合を考える。このとき、b=4までの計算は同じであるが、b≦iが成り立つため、計算部20は、求める位置はa*2番目のランと(a*2+1)番目のランとに挟まれた空白の上に存在すると判断する。ここで、(a*2+1)番目のランの開始位置におけるrank1の値をdとおく。dは、以下の数24によって計算される。
【0183】
【数24】
【0184】
上記数24の計算結果から、求める答えは、i+d=4+5=9である。
【0185】
以上のように、実施の形態及び実施例に示した情報処理装置100は、データ構造(完備辞書)を用いて、access、rank1、rank0、select1、及びselect0の全ての操作を行うことができる。そして、どの操作が行われる場合でも、3つの疎なビット列で構築された完備辞書におけるrank又はselectを数回実行することで、目的の値が求まっている。すなわち、本実施例における計算量は、疎なビット列で構築された完備辞書のrank又はselectと同じオーダーの計算量となるので、処理は実用面で十分高速なものとなる。
【0186】
上述したように、非特許文献2に開示された技術では、rank1の値を保持するビット列は存在するが、rank0の値を保持するビット列が存在しておらず、select0を高速に計算することが不可能であった。これに対して、本実施例では、データ構造11において、rank1とrank0とを交互に記録することで、データ構造11のサイズを、非特許文献2に記載の完備辞書と略同じサイズとしながら、select0とselect1とを高速に計算することができる。
【0187】
上述の実施の形態及び実施例は、データ構造において、rank1の値を保存したものと見なすこともできるが、ランの長さを単進符号化したものと見ることもできる。但し、非特許文献2に記載の技術では、単純にランの長さを単進符号化したビット列を用いていたのに対して、上述の実施の形態及び実施例では、空白を挟んだ2つのランの長さを合計した値を単進符号化したビット列と、ランを挟んだ2つの空白の長さを合計した値を単進符号化したビット列との2つが用いられる。これは、同じ記号の連続した長さをそのまま符号化する、従来のランレングス圧縮と大きく異なる工夫点である。