LaTeX/算法
LaTeX 有多个用于将算法排版成“伪代码”形式的软件包。它们提供了比统一风格(即所有内容都使用打字机字体)更具样式的增强功能,这样循环或条件语句等结构在视觉上与其他文本区分开来。伪代码通常放在一个算法环境中。对于排版用真实编程语言编写的真实代码,请考虑 源代码列表 中介绍的listings 软件包。
有四个值得注意的软件包:algorithmic、algorithm2e、algorithmicx 和 program。
该algorithmic软件包使用与algorithmicx软件包不同的命令集。它与revtex4-1不兼容。基本命令是
\STATE <text>
\IF{<condition>} \STATE {<text>} \ELSE \STATE{<text>} \ENDIF
\IF{<condition>} \STATE {<text>} \ELSIF{<condition>} \STATE{<text>} \ENDIF
\FOR{<condition>} \STATE {<text>} \ENDFOR
\FOR{<condition> \TO <condition> } \STATE {<text>} \ENDFOR
\FORALL{<condition>} \STATE{<text>} \ENDFOR
\WHILE{<condition>} \STATE{<text>} \ENDWHILE
\REPEAT \STATE{<text>} \UNTIL{<condition>}
\LOOP \STATE{<text>} \ENDLOOP
\REQUIRE <text>
\ENSURE <text>
\RETURN <text>
\PRINT <text>
\COMMENT{<text>}
\AND, \OR, \XOR, \NOT, \TO, \TRUE, \FALSE
完整的文档列在 [2] [失效链接] 中。大多数命令与algorithmicx等效项相似,但大小写不同。该软件包算法捆绑包位于 ctan 存储库 中,日期为 2009-08-24,描述了algorithmic环境(用于排版算法)和algorithm浮动包装器(见 下面),该包装器旨在环绕算法环境。
该algorithmic软件包建议用于 IEEE 期刊,因为它属于它们默认样式表的一部分。[1]
如何将 require/ensure 重命名为 input/output
\floatname{algorithm}{Procedure}
\renewcommand{\algorithmicrequire}{\textbf{Input:}}
\renewcommand{\algorithmicensure}{\textbf{Output:}}
该algorithm2e软件包(首次发布于 1995 年,根据 v5.2 手册,最近更新于 2017 年 7 月)允许排版具有大量自定义选项的算法。与algorithmic一样,该软件包也不与 Revtex-4.1 兼容。[2]
与algorithmic, algorithm2e不同,它提供了大量的自定义选项,让用户能够根据自己的需求调整算法。该 CTAN 手册 提供了详细的示例列表和完整的控制集。
通常,在\begin{algorithm}和\end{algorithm}之间使用
1. 声明一组关键字(排版为函数/运算符)、布局控制、标题、标题、页眉文本(出现在算法的主要步骤之前,例如:输入、输出)
2. 编写算法的主要步骤,每个步骤以 \ 结尾;
这可以类比为在开始实际文档之前编写 latex 前言。
该软件包的加载方式如下
\usepackage[]{algorithm2e}
以下是一个来自 v4.01 手册的简单示例:
\begin{algorithm}[H]
\KwData{this text}
\KwResult{how to write algorithm with \LaTeX2e }
initialization\;
\While{not at end of this document}{
read current\;
\eIf{understand}{
go to next section\;
current section becomes this one\;
}{
go back to the beginning of current section\;
}
}
\caption{How to write algorithms}
\end{algorithm}
它会生成以下内容
更多详细信息请参见托管在 ctan 网站 上的手册。
该algorithmicx软件包提供了一些流行的算法设计结构。在你的前言中加入\usepackage{algpseudocode}以使用算法环境编写算法伪代码(\begin{algorithmic}...\end{algorithmic})。你可能希望使用算法环境(\usepackage{algorithm})将你的算法代码包装在算法环境中(\begin{algorithm}...\end{algorithm})以生成具有编号算法的浮动环境。
命令\begin{algorithmic}可以给出可选参数为一个正整数,如果给出,则会使行号在该整数的倍数处出现。例如\begin{algorithmic}[5]将进入算法环境,并对每五行进行编号。
以下是用algorithmicx软件包排版基本算法的示例(请记住将\usepackage{algpseudocode}语句添加到你的文档前言中)
\begin{algorithmic}
\If {$i\geq maxval$}
\State $i\gets 0$
\Else
\If {$i+k\leq maxval$}
\State $i\gets i+k$
\EndIf
\EndIf
\end{algorithmic}
LaTeX 源代码可以写成程序员熟悉的格式,以便于阅读。但是,这不会影响文档中的最终布局。
基本命令具有以下语法
语句(\State 会创建一个新行,也可以在其他命令前面使用)
\State $x\gets <value>$
三种形式的 if 语句
\If{<condition>} <text> \EndIf
\If{<condition>} <text> \Else <text> \EndIf
\If{<condition>} <text> \ElsIf{<condition>} <text> \Else <text> \EndIf
第三种形式接受任意数量的\ElsIf{}子句。请注意,它是\ElsIf而不是\ElseIf.
循环
\For{<condition>} <text> \EndFor
\ForAll{<condition>} <text> \EndFor
\While{<condition>} <text> \EndWhile
\Repeat <text> \Until{<condition>}
\Loop <text> \EndLoop
前置条件和后置条件
\Require <text>
\Ensure <text>
函数
\Function{<name>}{<params>} <body> \EndFunction
\Return <text>
\Call{<name>}{<params>}
此命令通常与\State命令一起使用,如下所示
\Function{Increment}{$a$}
\State $a \gets a+1$
\State \Return $a$
\EndFunction
注释
\Comment{<text>}
注意从旧algorithmic软件包切换过来的用户:注释可以放在源代码中的任何地方;不像旧algorithmic软件包那样有限制。
该algorithmicx软件包允许你定义自己的环境。
要定义以开始命令开头、以结束命令结尾的块,请使用
\algblock[<block>]{<start>}{<end>}
这将定义两个命令\<start>和\<end>它们没有参数。它们显示的文本为\textbf{<start>}和\textbf{<end>}.
使用\algblockdefx可以指定开始和结束命令输出的文本以及这些命令的参数数量。在文本中,第 n 个参数用#n.
\algblockdefx[<block>]{<start>}{<end>}
[<startparamcount>][<default value>]{<start text>}
[<endparamcount>][<default value>]{<end text>}
引用。示例
\algblock[Name]{Start}{End}
\algblockdefx[NAME]{START}{END}%
[2][Unknown]{Start #1(#2)}%
{Ending}
\algblockdefx[NAME]{}{OTHEREND}%
[1]{Until (#1)}
\begin{algorithmic}
\Start
\Start
\START[One]{x}
\END
\START{0}
\OTHEREND{\texttt{True}}
\End
\Start
\End
\End
\end{algorithmic}
更高级的自定义和其它结构在algorithmicx手册中说明:http://mirror.ctan.org/macros/latex/contrib/algorithmicx/algorithmicx.pdf
该program软件包提供用于排版算法的宏。每行都在数学模式下设置,因此所有缩进和间距都是自动完成的。符号|variable_name|可以在普通文本、数学表达式或程序中使用,以指示变量名。使用\origbar在程序中获得正常的|符号。命令\A, \B, \P, \Q, \R, \S, \T和\Z排版相应的粗体字母,并将下一个对象作为下标(例如\S1排版{\bf S$_1$}等)。单引号正常工作,例如\S‘‘.
以下是用program软件包排版基本算法的示例(请记住将\usepackage{program}语句添加到你的文档前言中)
\begin{program}
\mbox{A fast exponentiation procedure:}
\BEGIN \\ %
\FOR i:=1 \TO 10 \STEP 1 \DO
|expt|(2,i); \\ |newline|() \OD %
\rcomment{This text will be set flush to the right margin}
\WHERE
\PROC |expt|(x,n) \BODY
z:=1;
\DO \IF n=0 \THEN \EXIT \FI;
\DO \IF |odd|(n) \THEN \EXIT \FI;
\COMMENT{This is a comment statement};
n:=n/2; x:=x*x \OD;
\{ n>0 \};
n:=n-1; z:=z*x \OD;
|print|(z) \ENDPROC
\END
\end{program}
命令\(和\)被重新定义为在迷你页面中排版算法,因此算法可以作为公式中的单个框出现。例如,要说明特定动作系统等效于 WHILE 循环,您可以编写
\[
\( \ACTIONS A:
A \EQ \IF \B{} \THEN \S{}; \CALL A
\ELSE \CALL Z \FI \QE
\ENDACTIONS \)
\EQT
\( \WHILE \B{} \DO \S{} \OD \)
\]
Dijkstra 条件和循环
\begin{program}
\IF x = 1 \AR y:=y+1
\BAR x = 2 \AR y:=y^2
\utdots
\BAR x = n \AR y:=\displaystyle\sum_{i=1}^n y_i \FI
\DO 2 \origbar x \AND x>0 \AR x:= x/2
\BAR \NOT 2 \origbar x \AR x:= \modbar{x+3} \OD
\end{program}
具有多个出口的循环
\begin{program}
\DO \DO \IF \B1 \THEN \EXIT \FI;
\S1;
\IF \B2 \THEN \EXIT(2) \FI \OD;
\IF \B1 \THEN \EXIT \FI \OD
\end{program}
逆向工程示例。
这是原始程序
\begin{program}
\VAR \seq{m := 0, p := 0, |last| := `` ''};
\ACTIONS |prog|:
|prog| \ACTIONEQ %
\seq{|line| := `` '', m := 0, i := 1};
\CALL |inhere| \ENDACTION
l \ACTIONEQ %
i := i+1;
\IF (i=(n+1)) \THEN \CALL |alldone| \FI ;
m := 1;
\IF |item|[i] \neq |last|
\THEN |write|(|line|); |line| := `` ''; m := 0;
\CALL |inhere| \FI ;
\CALL |more| \ENDACTION
|inhere| \ACTIONEQ %
p := |number|[i]; |line| := |item|[i];
|line| := |line| \concat `` '' \concat p;
\CALL |more| \ENDACTION
|more| \ACTIONEQ %
\IF (m=1) \THEN p := |number|[i];
|line| := |line| \concat ``, '' \concat p \FI ;
|last| := |item|[i];
\CALL l \ENDACTION
|alldone| \ACTIONEQ |write|(|line|); \CALL Z \ENDACTION \ENDACTIONS \END
\end{program}
这是转换后的更正版本
\begin{program}
\seq{|line| := `` '', i := 1};
\WHILE i \neq n+1 \DO
|line| := |item|[i] \concat `` '' \concat |number|[i];
i := i+1;
\WHILE i \neq n+1 \AND |item|[i] = |item|[i-1] \DO
|line| := |line| \concat ``, '' \concat |number|[i]);
i := i+1 \OD ;
|write|(|line|) \OD
\end{program}
该包还提供了一个宏,用于排版这样的集合\set{x \in N | x > 0}.
可以通过设置行号\NumberProgramstrue并使用以下方法关闭编号\NumberProgramsfalse
该algorithm环境
[edit | edit source]对于由algorithmic生成的算法,将其“浮动”到文档中的最佳位置,以避免将其拆分为多个页面,通常很有用。该algorithm环境提供了这一点以及其他一些有用的功能。通过将以下内容添加到您的文档前导中,将其包含进来。
\usepackage{algorithm}进入该环境的方式是
\begin{algorithm}
\caption{<your caption for this algorithm>}
\label{<your label for references later in your document>}
\begin{algorithmic}
<algorithmic environment>
\end{algorithmic}
\end{algorithm}
算法编号
[edit | edit source]该algorithm包的默认编号系统是按顺序对算法进行编号。这通常不可取,尤其是在大型文档中,根据章节进行编号更为合适。可以通过提供应重新开始编号的文档组件的名称来影响算法的编号。此选项的合法值为:part、chapter、section、subsection、subsubsection 或无(默认)。例如
\usepackage[chapter]{algorithm}
算法列表
[edit | edit source]当您使用图形或表格时,您可以在目录附近添加它们的列表;该algorithm包提供了一个类似的命令。只需在文档中的任何位置放置
\listofalgorithms
,LaTeX 就会打印文档中所有“algorithm”环境的列表,以及相应的页码和标题。
来自手册的示例
[edit | edit source]这是一个来自手册的示例 (官方手册,第 14 页)
\begin{algorithm} % enter the algorithm environment
\caption{Calculate $y = x^n$} % give the algorithm a caption
\label{alg1} % and a label for \ref{} commands later in the document
\begin{algorithmic} % enter the algorithmic environment
\REQUIRE $n \geq 0 \vee x \neq 0$
\ENSURE $y = x^n$
\STATE $y \Leftarrow 1$
\IF{$n < 0$}
\STATE $X \Leftarrow 1 / x$
\STATE $N \Leftarrow -n$
\ELSE
\STATE $X \Leftarrow x$
\STATE $N \Leftarrow n$
\ENDIF
\WHILE{$N \neq 0$}
\IF{$N$ is even}
\STATE $X \Leftarrow X \times X$
\STATE $N \Leftarrow N / 2$
\ELSE[$N$ is odd]
\STATE $y \Leftarrow y \times X$
\STATE $N \Leftarrow N - 1$
\ENDIF
\ENDWHILE
\end{algorithmic}
\end{algorithm}
参考文献
[edit | edit source]- 该算法包的官方手册,Rogério Brito (2009),http://mirrors.ctan.org/macros/latex/contrib/algorithms/algorithms.pdf