拙訳: 擬多項式時間アルゴリズムとは何か
上記の記事が分かりやすかったので訳してみます。翻訳に問題がある場合はコメントにてご指摘お願いいたします。
質問
擬多項式時間とは何でしょうか。多項式時間とは何が違うのでしょうか。
擬多項式時間アルゴリズムとして、例えば 0-1 ナップザック問題を
これらはなぜ多項式時間とみなされないのでしょうか。
回答
多項式時間と擬多項式時間の違いを理解するために、まず「多項式時間」とは何を意味するのかをきちんと形式的に把握する必要があります。
直感的には、多項式時間とは、ある
例えば 選択ソートは
をしらみつぶしに解く方法は
これらの実行時間はいずれも、入力サイズを記録する変数
例えば、選択ソートでは
この文脈において
問題の「入力サイズ」を以下のように定めます。
例えば、仮にソートアルゴリズムの入力が 32bit 整数の配列であれば、入力サイズは、配列の長さを
また、点の数が
この「入力サイズ」の定義の下で、多項式時間の形式的な定義は以下のようになります。
グラフやリスト、木などを扱うアルゴリズムであれば、この定義は、直感的なよく用いられる定義とある程度は一致します。
例えば、32bit 整数の配列をソートするアルゴリズムがあるとしましょう。選択ソートなどを使えば、
実行時間は配列の要素数
ところで、配列の要素数
入力のビット長
表しても
同様に、あるグラフに対して 深さ優先探索 をすることを考えてみましょう。
時間計算量は、グラフの辺の数を
もし、入力のグラフが隣接リストで表現されていれば、先ほど説明した通り、必要なビット長は
したがって、実行時間は
ところが、数に対して何らかの操作をするアルゴリズムを考えだすと、話はうまくいかなくなります。
ある数が素数か否かを判定する問題を考えてみましょう。与えられた
function isPrime(n):
for i from 2 to n - 1:
if (n mod i) = 0, return false
return true
ではこのコードの時間計算量はどの程度なのでしょうか。関数内のループは
それぞれのループごとに n mod i
を計算するための時間が必要となります(甘めに上限をとっても、
ですから、全体としてこのアルゴリズムは
2004 年に 3 人の計算機科学者たちが、 PRIMES is in P という、
ある数が素数か否かを検査する多項式時間アルゴリズムを提唱する論文を発表しました。
これは画期的な成果だと受け止められたわけですが、一体なにがすごいのでしょうか。私たちだって、例えば上のコードのような多項式時間アルゴリズムを知っているじゃないですか。
残念ながらそれは違うのです。思い出してください。アルゴリズムの計算量の形式的な定義は、入力のビット長の関数として考えなければならないのです。
私たちの知っているアルゴリズムは確かに
ある数
このアルゴリズムの実行時間は
これが、多項式時間と擬多項式時間の違いの核心です。ある面では、私たちの知るアルゴリズムは
しかしながら、形式的な定義のもとにおいては、それは多項式時間ではないのです。
どうしてこのアルゴリズムが多項式時間アルゴリズムではないかを直感的に理解するために、以下のように考えてみてください。
プログラムに長大な計算をさせることを考えます。入力として
10001010101011
を与えたとしましょう。これによって、完了するまでの最悪計算量が
仮に、この入力にたった 1bit を
100010101010111
と付け加えたとします。すると最悪計算量は
アルゴリズムがすべき計算の量が2倍になってしまうのです!
あるアルゴリズムが擬多項式時間アルゴリズムであるとは、実行時間が、入力に必要なビット長ではなく入力の数値の多項式で表されることを意味します。
私たちの知る素数判定アルゴリズムは
入力のビット長
"PRIMES is in P" という論文がなぜ画期的なのかというと、その実行時間がおよそ
これは入力のビット長の関数で表すと
では、どうしてこの擬多項式時間を多項式時間と区別するのに意味があるのでしょうか。私たちは数を操作する擬多項式時間アルゴリズムをたくさん知っています。
しかしながら、それらは厳密に言えば指数時間アルゴリズムです。この事実は暗号論的に重要です。
もし RSA 暗号を使いたければ、私たちは暗号に使う数が簡単には素因数分解できないことを信じなければなりません。
入力のビット長を巨大な数へと(例えば 1024bit など)増やすことによって、解くのに必要な時間を、
擬多項式時間アルゴリズムでは到底実行不可能なほど長くすることができます。
その一方で、もし私たちが多項式時間アルゴリズムを発見してしまえば、これは成り立たなくなります。
入力のビット数を増やすことで計算量を増やすことはできますが、その増加速度はたかが多項式的な増加量であり、指数的に増えるわけではありませんから。
そうは言ったものの、多くの場合において、入力サイズがそこまで大きくなることはないので、擬多項式時間アルゴリズムを使っても全く問題ありません。
例えば バケットソート の実行時間は、
ソートする配列の最大値を
もし
こうすると多項式時間アルゴリズムになります。これは 基数ソート がうまくいく仕組みにもなっています。
基数ソートにおいては、数を1桁ずつ処理していくことで、それぞれの桁の処理時間が
これは確かに多項式時間アルゴリズムになっています。なぜならソートする
参考になれば幸いです!
Discussion