前言

有时候论文里面需要写算法伪代码,所以这里记录下用LaTeX写一个算法的操作。如果想直接看效果,请直接翻到3)输出算法效果这一小节。

示例

1)第一步

首先在\begin{document}之前得加上:(看上去有点多?,没办法,这都是为了作出比较全,比较完善、好看的算法来

%基本算法包
\usepackage{calligra}
\usepackage{algorithm}
\usepackage{algorithmicx}
\usepackage{algpseudocode} 
\usepackage{amsmath} 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\usepackage{algorithm}% http://ctan.org/pkg/algorithm
%\PassOptionsToPackage{noend}{algpseudocode}% comment out if want end's to show
\usepackage{algpseudocode}% http://ctan.org/pkg/algorithmicx

\errorcontextlines\maxdimen

% begin vertical rule patch for algorithmicx (http://tex.stackexchange.com/questions/144840/vertical-loop-block-lines-in-algorithmicx-with-noend-option)
\makeatletter
% start with some helper code
% This is the vertical rule that is inserted
\newcommand*{\algrule}[1][\algorithmicindent]{\makebox[#1][l]{\hspace*{.5em}\thealgruleextra\vrule height \thealgruleheight depth \thealgruledepth}}%
% its height and depth need to be adjustable
\newcommand*{\thealgruleextra}{}
\newcommand*{\thealgruleheight}{.75\baselineskip}
\newcommand*{\thealgruledepth}{.25\baselineskip}

\newcount\ALG@printindent@tempcnta
\def\ALG@printindent{%
	\ifnum \theALG@nested>0% is there anything to print
	\ifx\ALG@text\ALG@x@notext% is this an end group without any text?
	% do nothing
	\else
	\unskip
	\addvspace{-1pt}% FUDGE to make the rules line up
	% draw a rule for each indent level
	\ALG@printindent@tempcnta=1
	\loop
	\algrule[\csname ALG@ind@\the\ALG@printindent@tempcnta\endcsname]%
	\advance \ALG@printindent@tempcnta 1
	\ifnum \ALG@printindent@tempcnta<\numexpr\theALG@nested+1\relax% can't do <=, so add one to RHS and use < instead
	\repeat
	\fi
	\fi
}%
\usepackage{etoolbox}
% the following line injects our new indent handling code in place of the default spacing
\patchcmd{\ALG@doentity}{\noindent\hskip\ALG@tlm}{\ALG@printindent}{}{\errmessage{failed to patch}}
\makeatother

% the required height and depth are set by measuring the content to be shown
% this means that the content is processed twice
\newbox\statebox
\newcommand{\myState}[1]{%
	\setbox\statebox=\vbox{#1}%
	\edef\thealgruleheight{\dimexpr \the\ht\statebox+1pt\relax}%
	\edef\thealgruledepth{\dimexpr \the\dp\statebox+1pt\relax}%
	\ifdim\thealgruleheight<.75\baselineskip
	\def\thealgruleheight{\dimexpr .75\baselineskip+1pt\relax}%
	\fi
	\ifdim\thealgruledepth<.25\baselineskip
	\def\thealgruledepth{\dimexpr .25\baselineskip+1pt\relax}%
	\fi
	%\showboxdepth=100
	%\showboxbreadth=100
	%\showbox\statebox
	\State #1%
	%\State \usebox\statebox
	%\State \unvbox\statebox
	%reset in case the next command is not wrapped in \myState
	\def\thealgruleheight{\dimexpr .75\baselineskip+1pt\relax}%
	\def\thealgruledepth{\dimexpr .25\baselineskip+1pt\relax}%
}
% end vertical rule patch for algorithmicx

2)第二步

在正文添加如下代码:

\begin{algorithm}[ht!]  %ht!参数是调整算法在文章中的位置
	%	\renewcommand{\algorithmicrequire}{\textbf{Input  \ \ :}}  %这样的指令可以让output和input的‘:’号在同一竖线上。但没必要,所以我注释了
	\renewcommand{\algorithmicrequire}{\textbf{Input:}}
	\renewcommand{\algorithmicensure}{\textbf{Output:}}
	\caption{xxx标题}  
	\label{xxx标签}
	\begin{algorithmic}[1] %每行显示行号
		\Require Faulty program  ($\textit{P}$)
		\Require Test cases $\left(\textit{Tests}\right) $
		\Require xxx 
		\Require xxx %细节就不多说了,略之
		\Ensure  xxx 
		
		\Function{xxx}{xxx} \label{xxx1}
		\For{xxx} 
		\myState{xxx} 
		\State xxx
		\EndFor 
		\EndFunction \label{xxx2}
		
		\Statex   %算法中的空行
		
		\Function{main}{}
		\State xxx
		\Repeat
			\If{xxx}
				\State xxx
			\Else  \Comment{xxx}  %注释
				\State xxx
				\For{xxx} 
					\If{xxx}
						\State xxx
					\EndIf
				\EndFor
				\State xxx
			\EndIf
			
		   	\State xxx
			\If{xxx}
				\State xxx
			\EndIf
		\Until{xxx}
		\EndFunction
	\end{algorithmic}
\end{algorithm}

3)输出算法效果

上面的代码编译过后,就是这样的输出:
在这里插入图片描述

一些网页总结

为了写上面这个算法很不容易,所以在此记录下有用的代码:

1) Vertical loop/block lines in algorithmicx with ‘noend’ option https://tex.stackexchange.com/questions/144840/vertical-loop-block-lines-in-algorithmicx-with-noend-option

有遇到过前后两行的竖线连不上的情况。这是因为我在前一行写的是一个大公式(包含除法符号,以及sum对应求和符号)。看了这个之后,发现可以用\myState自定义指令来解决。

2) Vertical line for pseudo code https://tex.stackexchange.com/questions/380674/vertical-line-for-pseudo-code

同上,另外一种解决方案是用algorithm2e这个包,但是我懒得重新学algorithm2e的对应语法,所以算了。

3.1) algorithm2e labelformat and size of list of algorithms https://tex.stackexchange.com/questions/205463/algorithm2e-labelformat-and-size-of-list-of-algorithms
3.2) Label specific state in the algorithmic environment https://tex.stackexchange.com/questions/62554/label-specific-state-in-the-algorithmic-environment

如何打标签。就在每行算法代码后加一个\label{xxx}就行。

4) algorithm, algorithmic, algorithmicx, algorithm2e, algpseudocode = confused https://tex.stackexchange.com/questions/229355/algorithm-algorithmic-algorithmicx-algorithm2e-algpseudocode-confused

各个算法包的区别。

5.1) algorithm2e – Floating algorithm environment with algorithmic keywords https://ctan.org/pkg/algorithm2e?lang=en
5.2) algorithm2e.sty — package for algorithms http://mirrors.cqu.edu.cn/CTAN/macros/latex/contrib/algorithm2e/doc/algorithm2e.pdf

一度想用algorithm2e 。

6.1) Indentation in latex algorithmic https://stackoverflow.com/questions/2018984/indentation-in-latex-algorithmic
6.2) Align Input and Output of algorithm to left https://tex.stackexchange.com/questions/353132/align-input-and-output-of-algorithm-to-left?noredirect=1&lq=1

主要是碰到了多个input的缩进问题。但还好,用多个\Require解决。。。而不是一个\Require

7) Insert a new line without \newline command https://tex.stackexchange.com/questions/153506/insert-a-new-line-without-newline-command

如何在不用\newline的情况下插入新行。

8) How to format for loop https://tex.stackexchange.com/questions/56871/how-to-format-for-loop

循环的写法。

9) Change while to repeat … until https://tex.stackexchange.com/questions/361522/change-while-to-repeat-until

repeat,until的写法。

10) Defining a function in pseudocode https://tex.stackexchange.com/questions/48131/defining-a-function-in-pseudocode

函数的写法。

11) Referring to function name in an algorithm https://tex.stackexchange.com/questions/111430/referring-to-function-name-in-an-algorithm

正文中引用函数名称。

12) Algorithm return statement does not begin on new line https://tex.stackexchange.com/questions/238574/algorithm-return-statement-does-not-begin-on-new-line

return的写法。其实可以直接用\textbf{return}就行了。。不一定要用\Return

13)How can I typeset function names as they appear in algorithmic environments? https://tex.stackexchange.com/questions/203713/how-can-i-typeset-function-names-as-they-appear-in-algorithmic-environments

这个答案应该还是有用的,不过我最后用的是{\scshape func-name}指令。

  1. How can I create vertical lines indentation in algorithm pseudo code correctly without end keywords? https://tex.stackexchange.com/questions/292815/how-can-i-create-vertical-lines-indentation-in-algorithm-pseudo-code-correctly-w/292838#292838

加不加end的一个参考。我觉得一般还是要加的、

总结

真的挺麻烦的。
搞这个算法搞了很久。
然后写这篇博客又用了45分钟。

在此记录之。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐