疑似コードを組む LaTeX パッケージには algorithm・algorithmic・algorithmicx(実際に使うのは algpseudocode)・algorithm2e という紛らわしい名前が並び、どれとどれが喧嘩するかで最初につまずきます。ところが本当に危ないのは、エラーを出す組み合わせではありません。TeX Live 2024 で全通り試したところ、algorithm2e と algpseudocode を一緒に読み込んでも 読み込み時のエラーは一切出ず、そのまま \For を書くと出力だけが静かに壊れました。このページでは、二層構造(外枠と中身)という設計を押さえたうえで、実際に再現したエラーメッセージ付きの衝突表、\State や \Procedure の書き方、キーワードを自分で宣言し直す方法、そして今から始める人への推奨を並べます。
二層構造——外枠を出すパッケージと、中身を書くパッケージ
疑似コードの組版は、役割の異なる二層に分かれます。第一層は 外枠——figure や table と同じようにページ上を漂い、「Algorithm 1」という番号つきのキャプションを持ち、相互参照でき、必要なら一覧まで作れる箱です。これを提供するのが algorithm で、中身では float パッケージの \newfloat を呼んで新しい浮動体を作っています(algorithm.sty の 31 行目に \RequirePackage{float}、82〜94 行目に \newfloat{algorithm}{htbp}{loa})。既定の見た目は \floatstyle{ruled}——上下に罫線が引かれる、あの体裁です。
第二層は 中身——\State(一行)、\While(繰り返し)、\If(分岐)といった、字下げと行番号を伴って疑似コードそのものを組む命令群です。ここで選択肢が三つに分かれます。古い algorithmic、その後継で自由度の高い algorithmicx(実務では、その上に載る配置 algpseudocode を読み込みます)、そして独立した別世界の algorithm2e。ややこしいのは名前だけでなく、algpseudocode を読み込んでも本文で使う環境名は algorithmic だという点です。パッケージ名と環境名がずれています。
| パッケージ | 層 | 役割 |
|---|---|---|
algorithm | 外枠 | float の上に \newfloat で作られた浮動体。\caption・\label・\listofalgorithms を担当。中身のパッケージと組で使う |
algorithmic | 中身(旧) | 最初の疑似コード環境。命令はすべて大文字(\STATE)。カスタマイズはほぼできない。algorithm と同じ algorithms バンドル同梱 |
algpseudocode | 中身(現行) | algorithmicx の上に載る標準の配置。命令は頭大文字(\State)。環境名は algorithmic のまま。algorithmicx は自動で読み込まれる |
algorithm2e | 両方 | 外枠と中身を自前で持つ独立した世界。\KwIn、\eIf、行末の \\; という独自文法。単独で使う |
どの組み合わせが壊れるか——TeX Live 2024 で全通り試した
結論から言えば、安全な組み合わせは algorithm + algpseudocode の一つだけ です。他の組み合わせは三通りの壊れ方をします。実際に走らせて得たメッセージを、そのまま並べます。
% SAFE — the intended pairing, compiles cleanly
\usepackage{algorithm}\usepackage{algpseudocode}
% two body packages: the environment name collides
\usepackage{algorithmic}\usepackage{algpseudocode}
! LaTeX Error: Command \algorithmic already defined.
% algorithm2e already owns a container — order changes only which name trips first
\usepackage{algorithm2e}\usepackage{algorithm}
! LaTeX Error: Command \listofalgorithms already defined.
\usepackage{algorithm}\usepackage{algorithm2e}
! LaTeX Error: Command \algorithm already defined.
! LaTeX Error: Command \algorithm* already defined.ここまでは分かりやすい失敗です。名前がぶつかった時点で LaTeX が止めてくれるので、ログの一行目を読めば原因が特定できます。問題は四つ目の組み合わせ——algorithm2e と algpseudocode です。両方の順序で試して、読み込み時のエラーはゼロでした。 それどころか、それぞれの環境を素直に使うだけなら両方とも動いてしまいます。ところが algorithmic 環境のなかで \For を書いた瞬間に崩れます。両者が \For や \If という 同じ名前を、エラーを出さない方法で定義している ためです。
\usepackage{algorithm2e}
\usepackage{algpseudocode} % loads fine. no error. no warning.
...
\begin{algorithmic}[1]
\State $x \gets 0$
\For{$i=1$ to $n$} \State $x \gets x+i$ \EndFor
\end{algorithmic}
% output is scrambled — lines merge and reorder — and only then:
! Missing number, treated as zero.
<to be read again> \ALG@b@2@EndFor@0
l.9 \EndForエラーは \EndFor の行で、しかも「数が足りない」という、原因からいちばん遠い言い方で出ます。プリアンブルの二行が犯人だとは読み取れません。これが四つの組み合わせのなかで最悪 な理由です。なお、これは \usepackage のオプションが食い違う「オプション衝突」とは 別の失敗 です。オプション衝突は「二度目の読み込みが、一度目に無かったオプションを要求したときに発動する」という部分集合の判定で起こるもので、Option clash for package という専用のメッセージが出ます。ここで起きているのは 命令名の重複——同じ \For を二つのパッケージが定義した、というだけの話です。
algpseudocode の書き方——\State から \Procedure まで
疑似コードは \begin{algorithmic} … \end{algorithmic} のなかに書き、省略可能な引数で行番号を制御 します。[0] で番号なし、[1] で全行に番号、[n] で n 行ごとに番号。要となるのが \State で、代入や手続き呼び出しなど 一文につき一つ 置きます。\While や \If のようにブロックを開く命令の前には \State を 置きません(それ自体が新しい行を始めます)。ブロックの中身は自動で字下げされ、ソース側の空白は出力に影響しません。命令が頭大文字(\State)なのは、全部大文字だった旧 algorithmic(\STATE・\WHILE)と見分けるいちばん早い手がかりです。
\State— 一文(一行)の始まり。\State $x \gets 1$のように使います。\For{cond}…\EndFor— 繰り返し。出力は「for … do」で始まり「end for」で閉じます。\ForAll{cond}もあります。\While{cond}…\EndWhile— 「while … do」/「end while」。\Repeat…\Until{cond}も使えます。\If{cond}…\ElsIf{cond}…\Else…\EndIf— 分岐。「if … then」「else if … then」「else」「end if」。\ElsIfと\Elseは省略できます。\Procedure{name}{args}…\EndProcedure— 手続き。「procedure name(args)」/「end procedure」。関数形の\Function{name}{args}…\EndFunctionも同じ形です。\Return— 戻り値。太字の「return」に続けて値が出ます。\Comment{...}— 行末コメント。右向きの三角 ▷ のあとに置かれます。\Require/\Ensure— 事前条件・事後条件。太字の「Require:」「Ensure:」が前に付きます。
\documentclass{article}
\usepackage{algorithm}
\usepackage{algpseudocode}
% declare your own keywords: Require/Ensure become Input/Output
\renewcommand{\algorithmicrequire}{\textbf{Input:}}
\renewcommand{\algorithmicensure}{\textbf{Output:}}
\begin{document}
\listofalgorithms
\begin{algorithm}
\caption{Power}\label{alg:p}
\begin{algorithmic}[1]
\Require $n \ge 0$
\Ensure $y = x^n$
\Procedure{Power}{$x, n$}
\State $y \gets 1$
\While{$n \neq 0$}
\State $y \gets y \times x$ \Comment{one step}
\State $n \gets n - 1$
\EndWhile
\State \Return $y$
\EndProcedure
\end{algorithmic}
\end{algorithm}
See Algorithm~\ref{alg:p}.
\end{document}これを二回コンパイルすると、上下に罫線を引いた箱が浮動体として置かれ、上端に「Algorithm 1 Power」が入ります。左端には 1 から 8 まで行番号が並び、\Require/\Ensure の行は再定義どおり「Input:」「Output:」と出ます——キーワードは飾りではなく 差し替え可能な宣言 です。同じ要領で \algorithmicwhile・\algorithmicdo・\algorithmicend などを書き換えれば、繰り返しや分岐の語も自由に変えられます。冒頭の \listofalgorithms は「List of Algorithms」の一覧を作り(algorithm.sty が loa という拡張子で目次ファイルを持っています)、本文の \ref{alg:p} は「See Algorithm 1.」に解決されます。番号と相互参照が落ち着くまで 必ず二回通してください。
外枠まわりで一点、よく誤解されている話を訂正しておきます。\begin{algorithm}[H] と書いて その場に固定 したいとき、float パッケージを自分で読み込む必要は ありません。algorithm.sty の 31 行目が \RequirePackage{float} なので、algorithm を読み込んだ時点で float は入っています。TeX Live 2024 で \usepackage{algorithm} だけの文書に [H] を書き、前後の地の文のあいだに箱が固定されることを確認しました。ついでに、algorithm 自身が受け取るオプション plain・ruled・boxed で枠の体裁を選べます(既定は ruled)。
algorithm2e——波括弧でブロックを渡し、行末に \\; を打つ世界
もう一方の大きな選択肢が algorithm2e です。外枠と中身を一つのパッケージで賄う自己完結型で、\usepackage[…]{algorithm2e} とプリアンブルで読み込みます。algorithm 環境そのものが浮動体なので、入れ子にする内側の環境はありません。文法も algpseudocode とは大きく違い、区別すべき点が三つあります。第一に、入出力は専用の命令 \KwIn{…}/\KwOut{…}(あるいは \KwData{…}/\KwResult{…})で書きます。第二に、分岐と繰り返しは中身を波括弧の引数として渡します——\eIf{cond}{then 側}{else 側}(e は「else 付き」の意)、\For{cond}{body}、\While{cond}{body}。第三に、各文の末尾に \\; が要ります。忘れると次の文が同じ行に流れ込みます。
\documentclass{article}
\usepackage[ruled, vlined, linesnumbered]{algorithm2e}
\SetKwInOut{Param}{Parameters} % declare a keyword of your own
\DontPrintSemicolon % hide the line-ending \;
\begin{document}
\begin{algorithm}[H]
\caption{Sum of positive entries}\label{alg:s}
\KwIn{an array $a[1..n]$}
\Param{tolerance $\epsilon$}
\KwOut{the sum $s$ of its positive entries}
$s \gets 0$\;
\For{$i \gets 1$ \KwTo $n$}{
\eIf{$a[i] > 0$}{
$s \gets s + a[i]$\tcp{keep it}
}{
\tcc{skip}
}
}
\Return $s$\;
\end{algorithm}
See Algorithm~\ref{alg:s}.
\end{document}ruled は上下に罫線とキャプション行を、vlined はブロック構造を示す縦線を(本文中から同じことをする命令が \SetAlgoLined、その旧名が \SetLine です)、linesnumbered は各行の番号を出します。\DontPrintSemicolon は行末の \\; を出力から隠す指定で、疑似コードを言語らしく見せたくないときに使います。コメントは \tcp{…}(// 形式、行末に付く)と \tcc{…}(/* … */ 形式、独立した行になる)の二種類。そして \SetKwInOut{Param}{Parameters} が このページの主題そのもの です——\KwIn や \KwOut は特別な存在ではなく、同じ宣言の仕組みで作られており、自分でもう一つ増やせます。同様に \SetKw・\SetKwFunction・\SetKwData があり、\KwTo や \Return の語も置き換えられます。[H] は algorithm2e 自身が実装しているので、ここでも float を明示的に読み込む必要はありません。
今から始めるならどちらを選ぶか
推奨は algorithm + algpseudocode です。理由は好みではなく、三つの実務的な事実にあります。第一に、この組み合わせだけが TeX Live 2024 で衝突なく通ります。第二に、外枠が float の上の普通の浮動体なので、\caption・\label・\ref・\listofalgorithms が図表とまったく同じ作法で動き、覚え直すことがありません。第三に、\State の一行一命令という書き方は、投稿先のテンプレートが前提にしていることが多いスタイルです。
algorithm2e を選ぶ理由もはっきりしています。入出力を明示的に宣言したい、ブロックを波括弧で渡す書き方や縦線のレイアウトが好み、キーワードを大量に自作したい——このいずれかに当てはまるなら、こちらのほうが素直です。どちらを選ぶにせよ、原則はひとつ。中身のパッケージは文書全体で一つに統一する こと。そして algorithm2e を使うなら algorithm は読み込まない ことです。両方を試したくなったら、同じ文書のなかで混ぜるのではなく、別ファイルで比べてください——プリアンブルの二行が、\EndFor の行の意味不明なエラーになって返ってきます。