原稿にコードを載せる方法は一つではありません。打ち込んだ通りに出す verbatim、実在のソースを色付け・行番号付きで見せる listings/minted、そしてもう一つが、言語に依存しない手続きを「Algorithm 1」と番号を振った枠で示す 擬似コード です。擬似コードは実在のコードと違い、図表と同じように紙面に浮動し、キャプション・通し番号・相互参照・アルゴリズム目次を持つ「フロート」として組まれます。このページは、その擬似コードを *掲載物* としてどう体裁よく置くか——とりわけキャプションと番号付け——に絞ります。命令を一つずつ解説した完全版は **/learn/math/algorithms** にあるので、ここでは二つの流派の見取り図と、それぞれの最小の完成例だけを示します。
擬似コードは「フロート」として置く
verbatim や listings が 本文の流れの中に コードを置くのに対し、擬似コードの掲載は フロート(浮動体) が基本です。フロートとは、figure(図)や table(表)のように、ページの切れ目を避けて適切な位置へ LaTeX が自動配置する箱のこと。これにより二つの利点が生まれます。第一に、「Algorithm 1」という通し番号付きのキャプションが付き、本文から \ref で参照できること。第二に、長い擬似コードがページ境界で不格好に分断されないこと——本文中に直接書く中身の環境はページをまたいで割れることがありますが、フロートの箱は一つにまとまって次ページへ送られます。
ここで最初に戸惑うのが、似た名前のパッケージが複数あることです。鍵になるのは 入れ物(番号付きの浮動枠)と中身(擬似コードそのもの)を別々のパッケージが担うという分業——ただし、この分業が当てはまるのは一方の流派だけです。実際には大きく二つの選択肢があります。
algorithm(入れ物)+algpseudocode(中身)の二層**——浮動枠・キャプション・番号はalgorithmフロートが、\State・\For・\Ifなどの擬似コード本体はalgpseudocode(algorithmicxの標準レイアウト)が受け持つ組み合わせ。algorithm2e(入れ物+中身を一つで)**——浮動枠・キャプション・\KwIn/\KwOut・\eIfなどをすべて自前で抱える自己完結型。algorithmは不要(併用するとフロート環境名が衝突する)。
最も大切な原則を先に言うと、中身の流派は文書全体でどちらか一方に統一することです。algpseudocode と algorithm2e は文法も思想もまったく異なり、両方を読み込むと \For や \If といった同名命令が衝突してエラーになります。番号や相互参照・アルゴリズム目次を確定させるため、どちらを使う場合も文書は通常どおり 2 回コンパイルします。
キャプション・番号・参照、そしてアルゴリズム目次
このページの主眼が、掲載物としての体裁です。どちらの流派でも、\caption{…} が 「Algorithm N」という見出しを作り、N は出現順に自動で振られます。直後に \label{キー} を置けば、本文から \ref{キー} でその番号を、\pageref{キー} でページ番号を引けます——図表の参照とまったく同じ作法です。
番号付きフロートのもう一つの恩恵が アルゴリズム目次 です。\listoffigures・\listoftables と並ぶもので、**\listofalgorithms** と書けば、各アルゴリズムの番号とキャプションを集めた一覧が(目次のように)生成されます。この一覧に載るのは \caption で与えた文言で、algorithm フロートでも algorithm2e でも同じく機能します。なお algorithm2e には \caption とは別に表題だけを付ける title 系の命令もありますが、そちらは目次に項目を追加しない点に注意してください。
キャプションを置く 位置 は流派で慣習が違います。algorithm フロートでは、図と同じく \caption を本体の 前後どちらにでも 置けます(多くの人は枠の上に置きます)。一方 algorithm2e では、\caption を環境の 末尾に置くのが流儀で、これがアルゴリズム目次の参照名にもなります。
流派1——algorithm + algpseudocode
外側を algorithm フロートで包み、内側の algorithmic 環境(パッケージ名は algpseudocode だが、環境名は algorithmic)に擬似コードを書きます。本体の命令はすべて 頭文字だけ大文字(\State・\While など)で、これが大文字だけの旧 algorithmic(\STATE)との見分け方です。よく使う命令だけ挙げると次のとおり。
\State— 一文(行)の始まり。文ごとに一つ置く。\For{…}…\EndFor/\While{…}…\EndWhile— ループ。\If{…}…\ElsIf{…}…\Else…\EndIf— 条件分岐。\Function{名}{引数}…\EndFunction、および\Return— 関数と返り値。\Require/\Ensure— 事前条件・事後条件(太字の見出し付き)。\Comment{…}— 行末コメント。
開始時の任意引数 [1] は行番号付けで、1 なら全行に番号、n なら n 行ごと、省略すれば番号なしです。次は累乗 y = xⁿ を計算する最小例。\caption の直後に \label を置いている点に注目してください。
\documentclass{article}
\usepackage{algorithm}
\usepackage{algpseudocode}
\begin{document}
\listofalgorithms
\begin{algorithm}
\caption{Calculate $y = x^n$}\label{alg:power}
\begin{algorithmic}[1]
\Require $n \geq 0$
\State $y \gets 1$
\While{$n \neq 0$}
\State $y \gets y \times x$
\State $n \gets n - 1$ \Comment{count down}
\EndWhile
\State \Return $y$
\end{algorithmic}
\end{algorithm}
アルゴリズム~\ref{alg:power} は累乗を計算する。
\end{document}コンパイルすると、上下に罫線を引いた枠が浮動して置かれ、上部に 「Algorithm 1 Calculate y = xⁿ」(番号は自動)が付きます。各行の左端に 1, 2, 3 … と行番号が振られ、本文の \ref{alg:power} はその番号(ここでは 1)に置き換わります。文書冒頭の \listofalgorithms には「1 Calculate y = xⁿ … ページ」という項目が並びます。命令一つ一つの出力や \ElsIf・\Function まで含む詳しい解説は **/learn/math/algorithms** を参照してください。
流派2——algorithm2e
algorithm2e は入れ物と中身を 一つのパッケージで自己完結させた別系統です(現行リリースは 5.2、2017 年)。\usepackage[…]{algorithm2e} を \begin{document} より前に読み込み、algorithm 環境そのものがフロートになります。スタイルは読み込みオプションで選び、ruled(上下に罫線)・boxed(全体を箱で囲む)・vlined/lined(ブロックに縦線)・plain(既定・装飾なし)、行番号は linesnumbered を付けます。文法の要点は三つ。
- 入力・出力は専用命令
\KwIn{…}/\KwOut{…}(または\KwData{…}/\KwResult{…})。それぞれ太字の「Input:」「Output:」などとして組まれる。 - 分岐・ループは中身を引数(波括弧)で渡す。if–then–else は
\eIf{条件}{真のとき}{偽のとき}、ループは\For{…}{中身}・\While{…}{中身}(\KwToで「to」)。 - **各文の末尾を
\\;(バックスラッシュ+セミコロン)で閉じる**。忘れると次の文が同じ行に続く。出力に「;」を見せたくなければ\DontPrintSemicolon。
\documentclass{article}
\usepackage[ruled,linesnumbered]{algorithm2e}
\begin{document}
\listofalgorithms
\begin{algorithm}
\caption{Sum of positive entries}\label{alg:sum}
\KwIn{an array $a[1..n]$}
\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]$\;
}{
skip\;
}
}
\Return $s$\;
\end{algorithm}
アルゴリズム~\ref{alg:sum} は正の要素を合計する。
\end{document}ruled で上下に罫線が引かれ上部にキャプション行が付き、linesnumbered で各行に番号が振られます。冒頭に太字の「Input:」「Output:」が並び、\For の行は for i ← 1 to n do と組まれて中身が字下げ、\eIf は if … then の真ブロックと else の偽ブロックを上下に置きます。各 \; の位置で改行が起こり、最終行に return s。\caption は \listofalgorithms の一覧にそのまま載ります。[H](その場に固定して浮動させない)や \SetAlgoLined(ブロックに縦線)など、見た目を細かく整える命令も含め、詳しい用法は **/learn/math/algorithms** にまとめてあります。
どちらを選ぶか
どちらも広く使われており、優劣ではなく流儀の違いです。次の早見表で当たりを付けてください。
| 観点 | algorithm + algpseudocode | algorithm2e |
|---|---|---|
構成 | 入れ物と中身の二層(2 パッケージ) | 一つで自己完結(入れ物+中身) |
本体の書き方 | \State を行頭に置く素直な命令体系 | ブロックの中身を波括弧で渡す |
入出力 | \Require / \Ensure | \KwIn / \KwOut(明示的) |
行末 | 不要 | \\; が必須 |
向く人 | 伝統的な見た目・学会テンプレが前提とする場合 | 入出力宣言や縦線・多言語キーワードを多用する場合 |
いずれの流派でも、\caption で番号付きの見出しを与え、\label/\ref で参照し、\listofalgorithms で一覧を作る——という掲載物としての扱いは共通です。繰り返しになりますが、本体パッケージは一つに絞ること。algorithm2e を使うなら入れ物の algorithm は読み込みません。命令の網羅的な一覧と長めの完成例は **/learn/math/algorithms に譲ります。実在のソースコードを色付き・行番号付きで載せたい(擬似コードではなく本物のコード)なら、/learn/code-verbatim/code-listings** の listings/minted が適任です。