コンピュータサイエンスにおいて、アルゴリズムの計算複雑度、あるいは単に複雑度とは、そのアルゴリズムを実行するために必要なリソースの量を指します。[ 1 ]特に、計算時間(一般的には必要な基本演算の数で測定される)とメモリの記憶容量要件に重点が置かれます。問題の複雑度とは、その問題を解決できる最良のアルゴリズムの複雑度を指します。
明示的に与えられたアルゴリズムの複雑さを研究することをアルゴリズム解析と呼び、問題の複雑さを研究することを計算複雑性理論と呼びます。アルゴリズムの複雑さは常にそのアルゴリズムによって解決される問題の複雑さの上限となるため、両分野は密接に関連しています。さらに、効率的なアルゴリズムを設計するには、特定のアルゴリズムの複雑さを解決すべき問題の複雑さと比較することがしばしば不可欠です。また、ほとんどの場合、問題の複雑さについて分かっているのは、それが最も効率的な既知のアルゴリズムの複雑さを超えないということだけです。したがって、アルゴリズム解析と計算複雑性理論の間には大きな重複があります。
アルゴリズムを実行するために必要なリソースの量は一般的に入力のサイズによって変化するため、複雑さは通常、関数n ↦ f ( n )として表されます。ここで、nは入力のサイズであり、f ( n )は最悪の場合の複雑さ(サイズnのすべての入力で必要とされるリソース量の最大値) または平均の場合の複雑さ(サイズnのすべての入力で必要とされるリソース量の平均) のいずれかです。時間計算量は一般的に、サイズnの入力に必要な基本操作の数として表されます。ここで、基本操作は、特定のコンピュータで一定の時間を要し、別のコンピュータで実行された場合でも一定の係数だけ変化すると想定されます。空間計算量は一般的に、サイズnの入力に対してアルゴリズムが必要とするメモリ量として表されます。
最も一般的に考慮されるリソースは時間である。「複雑性」という言葉が特に限定なしに用いられる場合、それは通常、時間複雑性を意味する。
複雑性理論では、通常の時間単位(秒、分など)は使用されません。なぜなら、それらは特定のコンピュータの選択や技術の進化に大きく依存するからです。例えば、今日のコンピュータは1960年代のコンピュータよりもはるかに速くアルゴリズムを実行できますが、これはアルゴリズムの本質的な特徴ではなく、コンピュータハードウェアの技術的進歩の結果です。複雑性理論は、アルゴリズムの本質的な時間要件、つまり、アルゴリズムがどのコンピュータにも課す基本的な時間制約を定量化しようとします。これは、計算中に実行される基本操作の数を数えることによって達成されます。これらの操作は、特定のマシン上で一定の時間(つまり、入力のサイズに影響されない)で実行されると想定され、しばしばステップと呼ばれます。
厳密に言えば、ビット複雑度とは、アルゴリズムを実行するために必要なビット操作の数を指します。ほとんどの計算モデルでは、ビット複雑度は定数倍を除いて時間複雑度と等しくなります。コンピュータでは、必要なマシンワード操作の数もビット複雑度に比例します。したがって、現実的な計算モデルでは、時間複雑度とビット複雑度は等価です。
もう一つ重要なリソースは、アルゴリズムを実行するために必要なコンピュータのメモリ容量です。
複数の参加者が相互に作用し合いながら実行される分散アルゴリズムの場合、最も重要なリソースは通信複雑度である。これは、実行参加者間の必要な通信量を指す。
算術演算の回数も、一般的に用いられる指標の一つです。この場合、算術複雑度という概念を用います。計算中に現れる数値の二進数表現のサイズの上限が分かっている場合、時間計算量は一般的に算術複雑度と定数倍の積となります。
多くのアルゴリズムでは、計算中に使用される整数のサイズに制限がなく、算術演算が一定時間で完了すると考えるのは現実的ではありません。したがって、この文脈では一般にビット複雑度と呼ばれる時間複雑度は、算術複雑度よりもはるかに大きくなる可能性があります。たとえば、 n × n整数行列の行列式の計算の算術複雑度は次のようになります。通常のアルゴリズム(ガウス消去法)の場合、同じアルゴリズムのビット複雑度はnに対して指数関数的になります。これは、計算中に係数のサイズが指数関数的に増加する可能性があるためです。一方、これらのアルゴリズムを多重モジュラ演算と組み合わせると、ビット複雑度はÕ ( n 4 )に削減できます。
ソートや検索において、一般的に考慮されるリソースはエントリ比較の回数である。データが適切に整理されていれば、これは一般的に時間計算量の良い指標となる。
アルゴリズムのステップ数を、考えられるすべての入力に対して数えることは不可能です。一般的に、入力のサイズが大きくなるにつれて複雑さも増すため、複雑さは通常、入力のサイズn (ビット単位) の関数として表され、したがって、複雑さはnの関数となります。しかし、同じサイズの入力であっても、アルゴリズムの複雑さは大きく異なる場合があります。そのため、複数の複雑さ関数が一般的に使用されます。
最悪ケースの複雑度は、サイズnのすべての入力に対する複雑度の最大値であり、平均ケースの複雑度は、サイズnのすべての入力に対する複雑度の平均値です(これは、特定のサイズの入力の数が有限であるため、理にかなっています)。一般に、「複雑度」という言葉が特に指定されずに使用される場合、それは最悪ケースの時間計算量を指します。
最悪の場合と平均的な場合の計算量を正確に算出することは一般的に困難です。さらに、これらの正確な値は、コンピュータや計算モデルの変更によって計算量が多少変化するため、実用的な用途はほとんどありません。また、nの値が小さい場合、リソースの使用量はそれほど重要ではないため、 nが小さい場合は、一般的に低い計算量よりも実装の容易さの方が重要になります。
こうした理由から、一般的にはnが大きい場合の計算量の挙動、すなわちnが無限大に近づくときの漸近的な挙動に注目する。そのため、計算量は一般的にビッグオー記法を用いて表現される。
例えば、整数乗算の通常のアルゴリズムの計算量はこれは定数が存在することを意味します最大n桁の 2 つの整数の乗算を以下の時間未満で実行できるこの境界は、最悪の場合の複雑さと平均的な場合の複雑さが次のようになるという意味で厳密である。つまり、定数も存在するということだこれらの複雑さは、基数はこれらの複雑な式には現れません。基数を変更しても定数のみが変わるからです。そして
計算の複雑さの評価は、単位時間内に実行される基本演算を定義する計算モデルの選択に依存します。計算モデルが明示的に指定されていない場合、一般的にはマルチテープチューリングマシンであると暗黙のうちに想定されます。これは、ランダムアクセスマシンなど、より現実的な計算モデルの多くが、ほとんどの問題で漸近的に等価であるためです。これは、整数乗算のような非常に特殊で困難な問題にのみ適用されます。証明には計算モデルの明示的な定義が必要である。
決定論的計算モデルとは、機械の連続する状態と実行される演算が、直前の状態によって完全に決定される計算モデルのことである。歴史的に見ると、最初の決定論的モデルは再帰関数、ラムダ計算、チューリングマシンであった。ランダムアクセスマシン(RAMマシンとも呼ばれる)のモデルも、実際のコンピュータにより近いものとして広く用いられている。
計算モデルが指定されていない場合、一般的にはマルチテープチューリングマシンであると想定されます。ほとんどのアルゴリズムにおいて、マルチテープチューリングマシンとRAMマシンでは時間計算量は同じですが、この等価性を得るためには、メモリへのデータの格納方法に注意が必要な場合があります。
非決定論的チューリングマシンなどの非決定論的計算モデルでは、計算のいくつかのステップで選択が行われる可能性があります。計算複雑性理論では、すべての可能な選択を同時に考慮し、非決定論的時間計算量は、常に最良の選択が行われる場合に必要な時間です。言い換えれば、計算は必要な数の(同一の)プロセッサで同時に実行され、非決定論的計算時間は、計算を完了した最初のプロセッサが費やす時間です。この並列性は、重ね合わせられたもつれ状態を介して、特定の量子アルゴリズム(例えば、整数の素因数を求めるショアのアルゴリズムなど)を実行することで、量子コンピューティングに部分的に適用可能です。
このような計算モデルはまだ現実的ではないものの、理論的には重要であり、主に「多項式時間」と「非決定性多項式時間」を上限として形成される複雑性クラスの同一性を問うP = NP問題に関連しています。決定性コンピュータでNPアルゴリズムをシミュレートするには、通常「指数時間」がかかります。問題が複雑性クラスNPに属するのは、非決定性マシンで多項式時間で解ける場合です。問題がNP完全であるのは、大まかに言えば、NPに属し、他のどのNP問題よりも簡単ではない場合です。ナップサック問題、巡回セールスマン問題、ブール充足可能性問題など、多くの組み合わせ問題はNP完全です。これらの問題すべてにおいて、最もよく知られているアルゴリズムは指数複雑性を持っています。これらの問題のいずれかが決定性マシンで多項式時間で解ける場合、すべてのNP問題も多項式時間で解けることになり、P = NPとなります。2017年現在一般的にP≠NPであると推測されており、実際的な意味合いとしては、NP問題の最悪のケースは本質的に解決が困難であり、つまり、興味深い長さの入力に対して、妥当な時間範囲(数十年!)よりも長い時間がかかるということである。
並列コンピューティングと分散コンピューティングは、複数のプロセッサに計算処理を分割し、それらを同時に動作させることで成り立っています。これらのモデルの主な違いは、プロセッサ間の情報伝送方法にあります。一般的に、並列コンピューティングではプロセッサ間のデータ伝送は非常に高速ですが、分散コンピューティングではネットワークを介してデータ伝送が行われるため、はるかに低速になります。
N個のプロセッサで計算を行うのに必要な時間は、少なくとも単一プロセッサで必要な時間のN乗以上でなければなりません。実際には、この理論的に最適な上限は一般的には達成できません。なぜなら、一部のサブタスクは並列化できず、一部のプロセッサは他のプロセッサからの結果を待たなければならない場合があるからです。
したがって、主な複雑性の問題点は、計算時間とプロセッサ数の積が、単一のプロセッサで同じ計算を行うのに必要な時間にできるだけ近くなるようなアルゴリズムを設計することである。
量子コンピュータとは、量子力学に基づいた計算モデルを持つコンピュータのことである。チャーチ=チューリングのテーゼは量子コンピュータにも当てはまる。つまり、量子コンピュータで解ける問題はすべてチューリングマシンでも解けるということである。しかし、理論的には、古典コンピュータよりも量子コンピュータの方がはるかに低い時間計算量で解ける問題もあるかもしれない。ただし、効率的な量子コンピュータの構築方法がまだ確立されていないため、これは今のところ純粋に理論上の話に過ぎない。
量子複雑性理論は、量子コンピュータを用いて解決される問題の複雑性クラスを研究するために開発された。これは、量子コンピュータによる攻撃に耐性のある暗号プロトコルを設計するポスト量子暗号において用いられる。
非公式には、問題の複雑さとは、未知のアルゴリズムも含め、その問題を解決するすべてのアルゴリズムの中で最小の複雑さを指しますが、そのような最小の複雑さは存在しない場合もあります。したがって、問題の複雑さは、その問題を解決するどのアルゴリズムの複雑さよりも大きくなることはありません。
したがって、ビッグオー記法で表現されるアルゴリズムの複雑さはすべて、対応する問題の複雑さの上限でもある。
一方で、問題の複雑さに対する非自明な下限値を得ることは一般的に難しく、そのような下限値を得るための方法はほとんどない。
ほとんどの問題を解決するには、すべての入力データを読み込む必要があり、通常、データのサイズに比例した時間が必要です。したがって、このような問題の複雑さは少なくとも線形であり、つまり、ビッグオメガ表記法を使用すると、複雑さは
コンピュータ代数や計算代数幾何学など、一部の問題の解は非常に大きくなる場合があります。このような場合、出力を書き出す必要があるため、複雑さは出力の最大サイズによって下限が定められます。たとえば、n個の不定元に関する次数dのn個の多項式方程式のシステムは、最大で次のようになります。解の数が有限であれば、解は複雑になります(これはベズーの定理です)。これらの解を書き出す必要があるため、この問題の複雑さはこの問題に対して、複雑度のアルゴリズムは既知であり、したがって漸近的に最適であると考えられる。
非線形下限は、ソートアルゴリズムに必要な比較回数を表します。したがって、最適なソートアルゴリズムは、その複雑さが であるため、漸近的に最適です。この下限は、n 個のオブジェクトを順序付ける方法がn !通りあるという事実から生じます。各比較によってこのn !通りの順序の集合が 2 つの部分に分割されるため、すべての順序を区別するために必要な比較の数Nは、これはつまりスターリングの公式による。
問題の複雑性の下限を示す標準的な方法は、問題を別の問題に還元することです。より正確には、サイズnの問題Aを問題Bのサイズf ( n )の部分問題にエンコードできると仮定し、 Aの複雑性は一般性を失うことなく、関数fはnとともに増加し、逆関数hを持つと仮定できる。すると、問題Bの複雑さは次のようになる。これは、 P ≠ NP (未解決の予想) の場合、すべてのNP 完全問題の複雑さが次のようになることを証明するために使用される方法です。すべての正の整数kに対して。
アルゴリズムの複雑さを評価することは、アルゴリズム設計において重要な部分であり、期待されるパフォーマンスに関する有用な情報を提供する。
ムーアの法則(現代のコンピュータの処理能力が指数関数的に増加するという法則)によって、アルゴリズムの複雑さの評価の重要性が低下するという誤解がよく見られます。しかし、これは間違いです。なぜなら、この処理能力の向上によって、大量の入力データ(ビッグデータ)を扱うことが可能になるからです。例えば、数百件のエントリからなるリスト(書籍の参考文献など)をアルファベット順に並べ替える場合、どのようなアルゴリズムでも1秒以内に処理を完了できます。一方、100万件のエントリからなるリスト(例えば、大都市の電話番号など)の場合、基本的なアルゴリズムでは処理に膨大な時間がかかります。比較を行うには 1 兆回の比較が必要となり、1 秒あたり 1000 万回の比較の速度で約 3 時間かかる。一方、クイックソートとマージソートではわずか 1 秒で済む。比較回数(前者の場合は平均ケースの複雑さ、後者の場合は最悪のケースの複雑さ)。n = 1,000,000 の場合、約30,000,000 回の比較が行われ、1 秒あたり 1000 万回の比較であればわずか 3 秒で済みます。
このように、複雑性の評価によって、実装前に多くの非効率なアルゴリズムを排除することが可能になります。また、すべてのバリエーションをテストすることなく、複雑なアルゴリズムを調整するためにも利用できます。複雑性の研究は、複雑なアルゴリズムの中で最もコストのかかるステップを特定することで、実装の効率改善のための取り組みをこれらのステップに集中させることを可能にします。