アルゴリズム
アルゴリズム（ ）とは、数学、コンピューティング、言語学、あるいは関連する分野において、問題を解くための手順を定式化した形で表現したものを言う。算法と訳されることもある。
「問題」はその「解」を持っているが、アルゴリズムは正しくその解を得るための具体的手順および根拠を与える。さらに多くの場合において効率性が重要となる。
コンピュータにアルゴリズムをソフトウェア的に実装するものがコンピュータプログラムである。人間より速く大量に計算ができるのがコンピュータの強みであるが、その計算が正しく効率的であるためには、正しく効率的なアルゴリズムに基づいたものでなければならない。
記録に残る最古のアルゴリズムは、エウクレイデスの原論のものである。その中でも、二つの整数の最大公約数を求めるユークリッドの互除法は、典型的なアルゴリズムとして知られている。
「アルゴリズム」という名称は、現在のイラクのバグダードにおける9世紀の数学者アル・フワーリズミーの名前から来ているといわれている。彼がインド数学を紹介した著作『インドの数の計算法』（825年）が、12世紀にチェスターのロバート（あるいはバースのアデラード）によってラテン語に翻訳され、『 アルゴリトミ・デ・ヌーメロ・インドルム』（直訳すると「インドの数におけるアルゴリトミ」）という題で、以後500年間にわたってヨーロッパ各国の大学で数学の主要な教科書として用いられた。この書は、冒頭に「（アル・フワリズミーに曰く）」という一節があるので『』と呼ばれていた。
1920〜30年代、計算可能性のための数学モデル（計算モデル）がいくつも提案された（チューリングマシン、帰納的関数、ラムダ計算など）。後にこれらの定義はすべて同等であることがわかり、それらにより同値な概念を「計算可能」とすることが提案された（チャーチ＝チューリングのテーゼ、提案者はスティーヴン・コール・クリーネ。なお、チューリングのほうを先とする専門家もいる）。したがって、現在では「これらによって『計算可能なもの』を計算する手続き」をアルゴリズムと呼ぶ。
アルゴリズムはコンピュータが情報を処理する基盤である。すなわち、プログラムは本質的にはアルゴリズムであり、コンピュータが特定のタスク（従業員の給与計算、学生の成績表の印刷など）を（指定された順序で）実行するためのステップをコンピュータに指示する。したがって、アルゴリズムはチューリング完全なシステムで実行可能な操作の並びとみなすこともできる。
…チューリングの命題についての非形式的な論証から、より強い命題が正当化される。すなわち、全てのアルゴリズムはチューリング機械でシミュレート可能である…Savage [1987] によれば、アルゴリズムはチューリング機械によって定義される計算過程である。
アルゴリズムは情報処理と結びついていることが多く、データは何らかの入力源（機器）から読み込まれ、結果は何らかの出力先（機器）に書かれるか、次の処理の入力となるよう保持される。保持されたデータはアルゴリズムを実行する実体の内部状態の一部とみなされる。実際、コンピュータでは状態をデータ構造に保持したりする。
このような計算過程について、アルゴリズムは厳密に定義されなければならず、ありうる全ての状況に適用可能な形で指定される。すなわち、どのような条件のステップでも、ケースバイケースで体系的に扱わなければならず、各ケースの扱い方は明確で（計算可能で）なければならない。
アルゴリズムは明確なステップの明確なリストなので、その計算順序は最も重要である。命令列は、先頭から最後尾に向かって逐次的に実行されるよう記述される。この考え方をより形式的にしたものが制御構造である。
以上の説明は、命令型プログラミングを前提としてアルゴリズムを定式化する場合である。これは、最も典型的な概念であり、タスクを離散的かつ機械的なものとして表すものである。その場合に特有の操作として、変数に値を設定する「代入」がある。これは、直観的にはメモリをメモ帳のようなものとみなすところから生まれた。
これ以外のアルゴリズムの概念化として、関数型プログラミングや論理プログラミングがある。
アルゴリズムは最終的に必ず停止しなければならないとする定義もある。例えば、クリーネは停止性のあるアルゴリズムを「」「」「」とした。停止しない可能性のある手続きについては、クヌースは「」と呼び、クリーネは「」「」と呼んでいる。
ミンスキーは、（特定の状態から開始された）アルゴリズムの停止性について次のように述べている。
しかしもし実行中のプロセスの長さが不明ならば、それを試すことは得策ではないかもしれない。何故なら、もしプロセスが永遠に続くなら、我々は答えを得られないかもしれないのだから。
アラン・チューリングが停止性問題として提起したとおり、任意のアルゴリズムと初期状態が与えられたとき、それが停止するかどうかを判定するアルゴリズム的手続きは存在しない。なお、アルゴリズムの停止性を解析するというものもある。
不完全な（あるいは間違った）アルゴリズムは、次のいずれかの結果となる。
クリーネはこれらをアルゴリズム内で検出してエラーメッセージを返すか、可能ならば無限ループに入らせることを提案した。また、結果が真理値である場合についてクリーネは第三の論理記号「formula_1」を使うことも提案している。そうすれば、命題を扱うアルゴリズムで何らかの値を常に生成できるとした。誤った答えを返す問題は、帰納法を使ったアルゴリズムに関する個別の「証明」で解決される。
通常、これ（アルゴリズムがμ再帰関数を正しく定義しているかという問題）には補助的な証拠を必要とする。それは例えば、個々の引数の値について、計算が一意な値で終了するかという帰納的証明の形式で示される。
アルゴリズムには様々な記法があり、自然言語、擬似コード、フローチャート、プログラミング言語などがある。アルゴリズムの自然言語表現は冗長であいまいになる傾向があり、複雑なアルゴリズムや技術的な場面では単独ではほとんど使用されない。擬似コードやフローチャートはアルゴリズムを構造的に表現でき、自然言語のようなあいまいさもほとんどない。プログラミング言語でアルゴリズムを示すこともよくある。
アルゴリズムの記述は、チューリング機械に関する記述として次の3つに分類される。
多くのアルゴリズムは、コンピュータプログラムとして実装されることを意図している。しかし、アルゴリズムの実装手段はほかにもあり、電気回路で実装したり、機械で実装したりすることもある。人間が算術を覚えるのも、脳内の神経網にアルゴリズムが実装されたものと見ることもできる。
簡単なアルゴリズムの例として、（整列されていない）有限長の数列（リスト）に含まれる（大きさが一定値以下の整数の）最大の数を見つけ出すアルゴリズムを考える。ここでは、リストに含まれる全ての数を調べる必要があるが、一度に調べらることができるのは1つだけであるとする。ここから得られるアルゴリズムを、日本語で記述すると次のようになる。
概念的記述:
次に、プログラミング言語的にやや形式的に記述すると、次のような擬似コードになる（「←」は代入を表し、「return」はその後に記された値を返してアルゴリズムが終了することを意味する）。
擬似形式的記述:
あるアルゴリズムの実行に必要な計算資源（時間や記憶領域）の量を見積もることは重要である。そのような量を定量的に求める分析法はアルゴリズム解析と呼ばれ、研究がなされてきた。例えば、上記のアルゴリズムの実行に必要な時間はリストの長さを "n" とするときO記法を用いて表せば O("n") となる。このアルゴリズムでは、（与えられたリスト以外には）常に（その時点での最大の数と、現在見ているリスト上の位置）2つの値だけを記憶しておけばよい。したがって、必要となる記憶領域の量は O(1) となるが、リストの長さ"n"を記憶して入力として与える場合にはそのための領域も含めるとすると O(log "n") になる。
同じ問題であっても、アルゴリズムが異なれば、必要とする時間や記憶領域の量も異なる。例えば、ソートには様々なアルゴリズムがあり、それぞれ必要な時間や記憶領域の量が異なる。
アルゴリズム解析は計算機科学の一部であり、特定のプログラミング言語や実装を前提とせずに、抽象的に解析を行うことが多い。これは、アルゴリズムの様々な属性に注目した他の数学的分野とも共通する。一般に、非常に単純化した汎用的表現として擬似コードが使われる。
アルゴリズムには様々な分類方法があり、それぞれに利点がある。
アルゴリズム分類の1つの方法として、実装手段による分類がある。
別の分類方法として、アルゴリズムの設計方法論やパラダイムで分類する方法がある。それぞれ異なるいくつかのパラダイムが存在する。さらに、個々のパラダイムの中にも様々な異なる形式のアルゴリズムが含まれている。以下に主なパラダイムを挙げる。
科学のどんな分野にも固有の問題があり、効率的なアルゴリズムが必要とされている。ある分野の問題はまとめて研究されることが多い。そのような分類として、探索アルゴリズム、ソートアルゴリズム、マージアルゴリズム、数値アルゴリズム、グラフアルゴリズム、文字列アルゴリズム、計算幾何アルゴリズム、組合せアルゴリズム、機械学習、暗号理論、データ圧縮アルゴリズム、構文解析などがある。
各分野はオーバーラップしており、ある分野でのアルゴリズムの進歩が、時には全く異なる分野での改善につながることがある。例えば、動的計画法は、本来、産業における資源消費の最適化のために発明されたが、現在では様々な分野での各種問題に適用されている。
アルゴリズムは、入力長に対する計算時間で分類される。あるアルゴリズムは入力長に対して線形時間で完了する。また別のアルゴリズムは指数時間以上かかるし、場合によっては完了しないこともある。さらに、問題によっては計算量の異なる複数のアルゴリズムが存在するし、効率的なアルゴリズムが全く知られていない問題もある。問題によっては、別の問題への写像が存在する。以上のようなことから、計算量による分類は、アルゴリズムについてではなく、問題について行うのが適当とされている。つまり、問題を解く最善のアルゴリズムの計算量に基づいて、問題を分類する。
アルゴリズムは計算能力によっても分類される。一般にアルゴリズムは計算能力によって階層的に分類される。「再帰的クラス」とは、全てのチューリング計算可能関数についてのアルゴリズムを含むクラスである。このような階層化によって、計算に必要とされる計算資源（時間とメモリ）を制限できる可能性が生じる。「部分再帰クラス」は、全てのチューリング計算可能な関数を得ることはできない。例えば、多項式時間で実行されるアルゴリズムには多くの重要な計算が含まれるが、チューリング計算可能な関数全体を含むことはない。原始再帰関数で実装されるアルゴリズムのクラスは、別の部分再帰的クラスの例である。
Burgin (2005, p. 24) は、関数を計算するアルゴリズムは有限ステップ後に必ず出力が決定されなければならないという一般的条件を緩めたアルゴリズムの汎用的定義を行った。彼は「超再帰的クラス」を「チューリングマシンで計算可能でない関数を計算可能なアルゴリズムのクラス」と定義した(Burgin 2005, p. 107)。これはハイパーコンピュータの手法の研究と密接に関係している。
アルゴリズム自体は一般に特許化できない。アメリカ合衆国では、抽象概念、数、信号の単純な操作だけから成る請求項は「プロセス」を構成しないとされるので、アルゴリズムは特許化できない。
しかし、アルゴリズムの具体的応用は特許化可能な場合がある。例えば、のケースでは、単純なフィードバックアルゴリズムを使った合成ゴムの硬化処理が特許として認められた。
データ圧縮アルゴリズムの分野では、ソフトウェア特許が論争の元になることが多く、例えばユニシスのLZWアルゴリズムの特許問題が有名である。
圧縮アルゴリズムで有名な特許問題は他に算術符号も挙げられる。算術符号で取得されている特許の範囲は3点であるとされている。算術符号によって断念されたソフトウェアやファイル形式は多く、代替品が相次いで開発された。
線型計画問題の解法であるカーマーカーのアルゴリズムは日本において特許無効審判がなされたが、2000年12月11日付けで特許庁に当該特許の放棄による特許権抹消の登録が行われたため、最終的に審判が却下された。
著作権の観点では、日本において著作権法3項にて明示的にアルゴリズムが同法の保護対象外であることが定められている。ただしアルゴリズムを記した文書や、アルゴリズムを実装したプログラムは著作物として保護対象となる（文書やプログラムを通して「アルゴリズムが保護」されるわけではない。つまりこの文章は、アルゴリズムについて書いてあるわけではない）。
アルゴリズム自体が保護される訳では無いが、CyberLink社のSVRT(計算不要と判断した部分は単にデータをコピーする技術)などの名称は承諾された者しか使えない。
暗号アルゴリズムには輸出規制されているものもある（アメリカでの例）。