使用单独的计数器创建自定义算法环境时出现问题

使用单独的计数器创建自定义算法环境时出现问题

我正在尝试为在 GPU 上运行的 CUDA 内核代码创建一个自定义算法环境,但对自定义 LaTeX 经验不足。它应该有一个单独的计数器,引用为内核 X通过 cleveref 包,并可能以某种方式出现在算法列表中作为内核,以将其与常规算法区分开来。

以下是我的 M(有点)WE。它使计数器工作,但引用不工作。此外,我无法在内核环境中正确包含放置说明符。

\documentclass[11pt]{article}
\usepackage{algorithm}
\usepackage{algorithmicx}
\usepackage{hyperref}
\usepackage[nameinlink, noabbrev]{cleveref}
\usepackage{float}

% Custom reference command
\newcommand{\sref}[1]{\textbf{\cref{#1}}}
\newcommand{\Sref}[1]{\textbf{\Cref{#1}}}

\newcounter{kernel}
\newcounter{temp}

\newenvironment{kernel}[1][ps]{%
    \setcounter{temp}{\value{algorithm}}%
    \setcounter{algorithm}{\value{kernel}}%
    \refstepcounter{kernel}%
    \begin{algorithm}[#1]%
    \floatname{algorithm}{Kernel}%
} {\end{algorithm}\setcounter{algorithm}{\value{temp}}}

\floatname{kernel}{Kernel}
\crefname{kernel}{kernel}{kernels}
\Crefname{kernel}{Kernel}{Kernels}

\begin{document}
\begin{algorithm}[htb!]
    \caption{Some really cool algorithm}
    \label{alg:algorithm1}

    \begin{algorithmic}
        \State $x \gets 1$
    \end{algorithmic}
\end{algorithm}

\begin{kernel}[htb!]
    \caption{Some other really cool algorithm}
    \label{alg:algorithm2}

    \begin{algorithmic}
        \State $y \gets 2$
    \end{algorithmic}
\end{kernel}

\begin{algorithm}[htb!]
    \caption{Another one...}
    \label{alg:algorithm3}

    \begin{algorithmic}
        \State $w \gets 3$
    \end{algorithmic}
\end{algorithm}

\begin{kernel}[htb!]
    \caption{The last one, I promise}
    \label{alg:algorithm4}

    \begin{algorithmic}
        \State $w \gets 4$
    \end{algorithmic}
\end{kernel}

As implied in~\ref{alg:algorithm1} aka~\autoref{alg:algorithm1} aka~\nameref{alg:algorithm1} aka~\cref{alg:algorithm1} aka~\sref{alg:algorithm1} it is really cool. The same goes for
~\ref{alg:algorithm2} aka~\autoref{alg:algorithm2} aka~\nameref{alg:algorithm2} aka~\cref{alg:algorithm2} aka~\sref{alg:algorithm2}.

\end{document}

我在这里找到的大多数示例要么与 algorithm2e 包有关,要么没有完全满足我的要求。

编辑:我成功地将放置说明符传递给环境algorithm,但它们似乎被忽略了,所以我可能仍然做错了什么。

答案1

\label命令保存了命令中最后使用的计数器的索引\refstepcounter。由于该\caption命令总是调用\refstepcounter{algorithm},因此\label始终与计数器相关联algorithm,因此 cleveref 会打印Algorithm而不是Kernel

我能想到的最简单的解决方案就是\label在调用之前调用\caption

但是这不会为您提供两个单独的标题列表。因此,定义一个新的浮动环境来保存算法实际上要容易得多。

\documentclass[11pt]{article}
\usepackage{algorithm}
\usepackage{algorithmicx}
\usepackage{hyperref}
\usepackage[nameinlink, noabbrev]{cleveref}
\usepackage{float}

% Custom reference command
\newcommand{\sref}[1]{\textbf{\cref{#1}}}
\newcommand{\Sref}[1]{\textbf{\Cref{#1}}}

% define a new float, with style `ruled`
\floatstyle{ruled}
\newfloat{kernel}{htbp}{lok}
\floatname{kernel}{Kernel}

\crefname{kernel}{kernel}{kernels}
\Crefname{kernel}{Kernel}{Kernels}

\begin{document}

\begin{algorithm}[htb!]
    \caption{Some really cool algorithm}
    \label{alg:algorithm1}

    \begin{algorithmic}
        \State $x \gets 1$
    \end{algorithmic}
\end{algorithm}

\begin{kernel}[htb!]
    \caption{Some other really cool algorithm}
    \label{alg:algorithm2}

    \begin{algorithmic}
        \State $y \gets 2$
    \end{algorithmic}
\end{kernel}

\begin{algorithm}[htb!]
    \caption{Another one...}
    \label{alg:algorithm3}

    \begin{algorithmic}
        \State $w \gets 3$
    \end{algorithmic}
\end{algorithm}

\begin{kernel}[htb!]
    \caption{The last one, I promise}
    \label{alg:algorithm4}

    \begin{algorithmic}
        \State $w \gets 4$
    \end{algorithmic}
\end{kernel}

As implied in~\ref{alg:algorithm1} aka~\autoref{alg:algorithm1}
aka~\nameref{alg:algorithm1} aka~\cref{alg:algorithm1} aka~\sref{alg:algorithm1}
it is really cool. The same goes for
~\ref{alg:algorithm2} aka~\autoref{alg:algorithm2}
aka~\nameref{alg:algorithm2} aka~\cref{alg:algorithm2} aka~\sref{alg:algorithm2}.

\listof{kernel}{List Of Kernels}

\listof{algorithm}{List Of Algorithms}

\end{document}

输出

相关内容