4

I'm struggling with something that seems pretty complicated to me, but maybe there's a way better solution already out there. If not, I'd really appreciate any help with getting the following problem solved.

I have a long algorithm in my document that I've broken in two. It's written using algorithmicx. My requirements are as follows:

  1. The algorithm number (e.g. Algorithm 1.3) should be the same for both since it's the same algorithm.
  2. At the end of the first half, I want a line that says the algorithm is continued later.
  3. If the second half ends up just on the next page, I just want to say "Continued on next page". If it's on a later page than the next page, I want the note to say "Continued on page x".
  4. I want the "Continued on page x" to hyper-reference the page of the second half of the algorithm.

I realize in point #3 that it would be unusual for the second half not to end up on the next page, but I'm curious about this as an exercise. Also, you might want to describe half of a lengthy algorithm in the text, show pseudocode for the first half, then talk about the second half in the text again before continuing the pseudocode, in which case they'd like end up spaced apart by multiple pages.

My solution for these points so far:

  1. This is solved using \ContinuedFloat of the subcaption package; without this command, the second half of the algorithm would get an incremented number in the title.
  2. This is solved with zref and a conditional check on the absolute page number, based on a question I asked here.
  3. See 2.
  4. This is the problematic point. Right now, I have a separate \label in each algorithm environment, but when hyperlinked, the link in the second half returns me to the first (correct), but the link in the first half just takes me to the first half (incorrect), when it should take me to the second half.

I think the problem with 4 is a conflict between the subcaption and hyperref packages, in that links to figures generally take you to the top of the figure, so a link to the second half of the algorithm takes me to the top of the first one since I've used a \ContinuedFloat so it considers them both one big float. Also, when I build, I get a warning "destination with the same identifier (name{algorithm0.1}) has already been used". However, the page numbers shown in the PDF are correct, they just don't link correctly.

I've provided a MWE below. Notice that when you click the "Continued on" link at the bottom of the first half of the algorithm, it doesn't take you to the second half.

Is there a solution for this? Also, if there's an overall solution for splitting up algorithms that would do everything I'm trying to do here, that would be great.

Many thanks to everyone who even reads this admittedly long-winded question.

MWE:

\documentclass[12pt, oneside]{report} 

\usepackage[english]{babel}    
\usepackage{blindtext}

\usepackage[font=small,tableposition=top]{caption}
\usepackage[skip=6pt,hypcap=true]{subcaption}

\usepackage[chapter]{algorithm}
\usepackage{algorithmicx,algpseudocode}

\usepackage[user,abspage]{zref}
% macro to compare two absolute page numbers to see if the first is greater than the second by more than one
\makeatletter
\newcommand\cmpabspage[2]{%
   \ifnum\zref@extract{#1}{abspage}>\numexpr\zref@extract{#2}{abspage}+1\relax
       \expandafter\@firstoftwo
   \else
       \expandafter\@secondoftwo
   \fi
}
\makeatother

\usepackage[pdftex]{hyperref}
\hypersetup{colorlinks=true}
\newcommand{\pagename}{page }

\begin{document}

\blindtext

Pseudocode is shown in Algorithm \ref{longalg}.

\begin{algorithm}[!htbp]
  \caption{Long algorithm part 1}
    \label{longalg}
    \label{longalg-1}
    \zlabel{z.longalg-1}

\begin{algorithmic}[1]  

        \State The first part of a lengthy algorithm would go here. 

        \cmpabspage{z.longalg-2}{z.longalg-1}
        {\Statex Continued on \pagename \pageref{longalg-2}}
        {\Statex Continued on next page}

    \algstore{algstore.longalg}
    \end{algorithmic}
\end{algorithm}

\Blindtext[4][4]

\begin{algorithm}[!htbp]

\ContinuedFloat
\caption{Long algorithm part 2}
\label{longalg-2}
\zlabel{z.longalg-2}

\begin{algorithmic}[1]
        \algrestore{algstore.longalg}

        \cmpabspage{z.longalg-2}{z.longalg-1}
        {\Statex Continued from \pagename \pageref{longalg-1}}
        {\Statex Continued from previous page}

        \State The second part of a lengthy algorithm would go here.    

    \end{algorithmic}
\end{algorithm}

\end{document}

Thanks.

2
  • You should add \usepackage[english]{babel} to your code example so that it compiles.
    – lockstep
    Commented Jul 31, 2011 at 22:00
  • This compiles fine for me using MikTex (2.8 I think) and TeXnic Center 2 in Windows 7. Not sure why it won't for you, but I've added babel as per your suggestion. Thanks.
    – SSilk
    Commented Jul 31, 2011 at 23:15

2 Answers 2

5

The rub is the incorrect package load order regarding hyperref. Therefore the warning pdfTeX warning (ext4): destination with the same id entifier (name{algorithm.0.1}) has been already used, duplicate ignored will be issued when compiling your example code.

The algorithm package loads and uses the float package, and the float package should be loaded before the hyperref package, but should be used after the hyperref package. (See hyperref README for details)

This conflict can be solved by loading the float package manually (before hyperref) and loading the algorithm package after hyperref; this one gives me a correct hyperlink:


\documentclass[12pt, oneside]{report} 

\usepackage[english]{babel}    
\usepackage{blindtext}

\usepackage[font=small,tableposition=top]{caption}
\usepackage[skip=6pt,hypcap=true]{subcaption}

\usepackage{float}

\usepackage[user,abspage]{zref}
% macro to compare two absolute page numbers to see if the first is greater than the second by more than one
\makeatletter
\newcommand\cmpabspage[2]{%
   \ifnum\zref@extract{#1}{abspage}>\numexpr\zref@extract{#2}{abspage}+1\relax
       \expandafter\@firstoftwo
   \else
       \expandafter\@secondoftwo
   \fi
}
\makeatother

\usepackage[pdftex]{hyperref}
\hypersetup{colorlinks=true}
\newcommand{\pagename}{page }

\usepackage[chapter]{algorithm}
\usepackage{algorithmicx,algpseudocode}

\begin{document}

\blindtext

Pseudocode is shown in Algorithm \ref{longalg}.

\begin{algorithm}[!htbp]
  \caption{Long algorithm part 1}
    \label{longalg}
    \label{longalg-1}
    \zlabel{z.longalg-1}

\begin{algorithmic}[1]  

        \State The first part of a lengthy algorithm would go here. 

        \cmpabspage{z.longalg-2}{z.longalg-1}
        {\Statex Continued on \pagename \pageref{longalg-2}}
        {\Statex Continued on next page}

    \algstore{algstore.longalg}
    \end{algorithmic}
\end{algorithm}

\Blindtext[4][4]

\begin{algorithm}[!htbp]

\ContinuedFloat
\caption{Long algorithm part 2}
\label{longalg-2}
\zlabel{z.longalg-2}

\begin{algorithmic}[1]
        \algrestore{algstore.longalg}

        \cmpabspage{z.longalg-2}{z.longalg-1}
        {\Statex Continued from \pagename \pageref{longalg-1}}
        {\Statex Continued from previous page}

        \State The second part of a lengthy algorithm would go here.    

    \end{algorithmic}
\end{algorithm}

\end{document}

See also: https://texfaq.org/FAQ-hyperdupdest

1
  • +1, and you were right about downvoting my answer to zero. I will delete it as soon as its acceptance is revoked.
    – lockstep
    Commented Aug 1, 2011 at 17:18
1

I would handle your page reference problem by defining a new counter that would be used to circumvent hyperref's "destination with the same identifier (name{algorithm0.1}) has already been used" warning. The idea of keeping something 'independent' from something else instinctively suggests that. The new counter would only be used for referencing the page, although it could even be used to correctly reference the second part of the algorithm as well. To that end, the following abbreviated changes does the trick for me:

...
\newcounter{newalgcounter}% New counter definition
\renewcommand{\thenewalgcounter}{\thechapter.\arabic{newalgcounter}}% New counter typesetting (this should match that of the algorithm package
...
\begin{algorithm}[!htbp]% Part 1 of algorithm
  \caption{Long algorithm part 1}
  ...
  {\Statex Continued on \pagename \pageref{longalg-2-page}}% Reference to new counter
  ...
\end{algorithm}
...
...
\begin{algorithm}[!htbp]% Part 2 of algorithm
  \ContinuedFloat
  \setcounter{newalgcounter}{\value{algorithm}}% update new algorithm counter
  \caption{Long algorithm part 2}
  ...
  \refstepcounter{newalgcounter} \label{longalg-2-page}% New counter incremented & labelled
\end{algorithm}
...

Although this does not get rid of the reference of a duplicate name (from hyperref), it can also be avoided by defining a duplicate environment to that of algorithm - something like \begin{dupalgorithm}...\end{dupalgorithm}. However, that depends on your coding preferences.

1
  • I tried Lockstep's short fix, and it seems to work for my needs now. Thanks for the suggestion though.
    – SSilk
    Commented Jul 31, 2011 at 23:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .