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等价物类似,但大小写不同。该软件包algorithms bundle在 ctan 存储库 中,日期为 2009-08-24,描述了该软件包algorithmic环境(用于排版算法)和algorithm浮动包装器(参见 下面),它旨在围绕 algorithmic 环境进行包装。
该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}放入前言中,以使用 algorithmic 环境编写算法伪代码(\begin{algorithmic}...\end{algorithmic})。您可能希望使用 algorithm 环境(\usepackage{algorithm})将您的 algorithmic 代码包装到 algorithm 环境中(\begin{algorithm}...\end{algorithm}),以生成具有编号算法的浮动环境。
命令\begin{algorithmic}可以接受一个正整数的可选参数,如果提供该参数,将导致在该整数的倍数处进行行编号。例如\begin{algorithmic}[5]将进入 algorithmic 环境并为每五行编号。
下面是使用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}
这些命令\(和\)被重新定义为在 minipage 中排版算法,因此算法可以作为公式中的单个框出现。例如,要说明某个特定动作系统等效于 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包文档
环境对于由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}
算法编号
环境输入该algorithm包的默认编号系统是对算法进行顺序编号。这通常不可取,特别是在大型文档中,根据章节进行编号更合适。可以通过提供文档组件的名称来影响算法的编号,在该组件内应重新开始编号。此选项的合法值为:part、chapter、section、subsection、subsubsection 或 nothing(默认值)。例如
\usepackage[chapter]{algorithm}
算法列表
环境当使用图形或表格时,您可以在目录附近添加它们的列表;该algorithm包提供了类似的命令。只需在文档中的任何位置放置
\listofalgorithms
,LaTeX 就会打印文档中“算法”环境的列表,并附带相应的页面和标题。
来自手册的示例
环境这是一个取自手册的示例(官方手册,第 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}
参考文献
环境- 该算法包的官方手册,Rogério Brito(2009),http://mirrors.ctan.org/macros/latex/contrib/algorithms/algorithms.pdf