líneas de alcance de sangría rotas en pseudocódigo alg

líneas de alcance de sangría rotas en pseudocódigo alg

Estoy intentando proporcionar una línea vertical que muestre la sangría en un algoritmo. estoy siguiendoesta respuesta, pero cuando agrego algunas matemáticas que son superiores a la altura de la línea, las líneas se rompen. Este es el resultado y también proporciono el código. ¿Se puede solucionar este problema?

ingrese la descripción de la imagen aquí

\documentclass{article}

\usepackage{amsmath}                              % For \eqref
\usepackage{amssymb}                             % For mathematical symbols
\usepackage{amsbsy}                                % For bold symbol greek letters

\usepackage[noend]{algpseudocode}
\usepackage{algorithm}
\usepackage{algorithmicx}


\makeatletter
% start with some helper code
% This is the vertical rule that is inserted
\newcommand*{\algrule}[1][\algorithmicindent]{\makebox[#1][l]{\hspace*{.5em}\vrule height .75\baselineskip depth .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
    \addvspace{-3pt}% FUDGE for cases where no text is shown, to make the rules line up
    \else
    \unskip
    % 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
% end vertical rule patch for algorithmicx
\makeatother

% for bmatrix with alignment
\makeatletter
  \renewcommand*\env@matrix[1][*\c@MaxMatrixCols c]{%
    \hskip -\arraycolsep
    \let\@ifnextchar\new@ifnextchar
  \array{#1}}
\makeatother



\begin{document}

   \begin{algorithm}
        \caption{Arbitrary Algorithm}\label{IS2OSLS}
        \begin{algorithmic}[1]
            \Require A matrix $\mathbf{A}$ of size $m\times n$.
            \Ensure Something.
            \For{$i$ in $m$}
                   \State{$\mathbf{X} \gets \begin{bmatrix}[rrr]  \boldsymbol x_i  & \boldsymbol x_j & \ldots \end{bmatrix}^\intercal $} \Comment{get coordinates}

                \For{$j$ in $n$}
                    \If{$i=j$}
                        \State Select a random action
                    \Else
                        \If{$i=j^3+1$}
                            \State Stay silent 
                            \State $j \gets \begin{cases} a & b \\ c & d \end{cases} $
                        \Else 
                            \State $i \gets \mathbf{J}^\intercal$
                            \State Break
                        \EndIf
                    \EndIf
                \EndFor
            \EndFor
        \end{algorithmic}
    \end{algorithm}

\end{document}

ACTUALIZAR

Según su código, le doy otro ejemplo en el que puede ver que las reglas se superponen a la declaración de devolución.

\documentclass{article}

\usepackage{mathtools}
\usepackage{amssymb}
\usepackage{amsbsy}

\usepackage[noend]{algpseudocode}
\usepackage{algorithm}
\usepackage{algorithmicx}

\newcommand*{\algrule}[1][\algorithmicindent]{\hspace*{.5em}\vrule\vrule
width 0pt height .75\baselineskip depth .25\baselineskip\hspace*{\dimexpr#1-.5em}}

\makeatletter
\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
    \addvspace{-3pt}% FUDGE for cases where no text is shown, to make the rules line up
    \else
    \unskip
    % 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}
\patchcmd{\ALG@doentity}{\noindent\hskip\ALG@tlm}{\ALG@printindent}{}{\errmessage{failed to patch}}
\makeatother

\AtBeginEnvironment{algorithmic}{\lineskip0pt}

\newcommand*\Let[2]{\State #1 $\gets$ #2}


\begin{document}

\begin{algorithm}
  \caption{Test 2
    \label{alg:interact}}
  \begin{algorithmic}[0]
    \Require{$\mathcal{M} := \left\{ \mathcal{N}, \mathcal{E} \right\}$ and  $\mathcal{G}$}
    \Statex
    \Function{test}{$\mathcal{M}, \mathcal{G}$}
      \Let{$\mathcal{S}$}{$\emptyset$} 
      \For{$e_i \in \mathcal{E}$}
        \For{$g_i \in \mathcal{G}$}
          \Let{$\mathcal{I}$}{$e_i  \cap g_i$}
          \If{$\mathcal{I} \neq \emptyset $} 
            \Let{$\left\{n_k \right\}$}{$\mathcal{I}$} 
            \Let{$\phantom{\left\{n_k \right\} }\mathllap{ \mathcal{S}}$}{$\mathcal{S} \bigcup_k \left\{ n_k, s_k\right\} $}
            \Let{$\phantom{\left\{n_k \right\} }\mathllap{ \mathcal{N}}$}{$\mathcal{N} \bigcup_k \left\{n_k \right\}$}
            \Let{$\phantom{\left\{n_k \right\} }\mathllap{\mathcal{T}}$}{subdivide($e_i, \mathcal{I}$)} 
            \Let{$\phantom{\left\{n_k \right\} }\mathllap{\mathcal{E}}$}{$\mathcal{E} \cup \mathcal{T}$}  
          \EndIf
        \EndFor
      \EndFor
      \State \Return{$\mathcal{W}, \mathcal{N}, \mathcal{E}$}
    \EndFunction
  \end{algorithmic}
\end{algorithm}

\end{document}

Lo que da

ingrese la descripción de la imagen aquí

ACTUALIZACIÓN 2

El nuevo código es

\documentclass{article}

\usepackage{mathtools}
\usepackage{amssymb}
\usepackage{amsbsy}

\usepackage[noend]{algpseudocode}
\usepackage{algorithm}
\usepackage{algorithmicx}

\newcommand*{\algrule}[1][\algorithmicindent]{\hspace*{.5em}\vrule\vrule
width 0pt height \baselineskip depth .25\baselineskip\hspace*{\dimexpr#1-.5em}}

\makeatletter
\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
    % 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}
\patchcmd{\ALG@doentity}{\noindent\hskip\ALG@tlm}{\ALG@printindent}{}{\errmessage{failed to patch}}
\makeatother

\AtBeginEnvironment{algorithmic}{\lineskip0pt}

\newcommand*\Let[2]{\State #1 $\gets$ #2}


\algtext*{EndWhile}% Remove "end while" text
\algtext*{EndFor}% Remove "end for" text
\algtext*{EndIf}% Remove "end if" text
\algdef{SE}[DOWHILE]{Do}{doWhile}{\algorithmicdo}[1]{\algorithmicwhile\ #1}%

% increase line spacing for algorithmicx
\usepackage{etoolbox}
\makeatletter
\expandafter\patchcmd\csname\string\algorithmic\endcsname{\itemsep\z@}
{\itemsep=0.2ex plus2pt}{}{}
\makeatother

\begin{document}

\showoutput

\begin{algorithm}
  \caption{Test 2
    \label{alg:interact}}
  \begin{algorithmic}[0]
    \Require{$\mathcal{M} := \left\{ \mathcal{N}, \mathcal{E} \right\}$ and  $\mathcal{G}$}
    \Statex
    \Function{test}{$\mathcal{M}, \mathcal{G}$}
      \Let{$\mathcal{S}$}{$\emptyset$} 
      \For{$e_i \in \mathcal{E}$}
        \For{$g_i \in \mathcal{G}$}
          \Let{$\mathcal{I}$}{$e_i  \cap g_i$}
          \If{$\mathcal{I} \neq \emptyset $} 
            \Let{$\left\{n_k \right\}$}{$\mathcal{I}$} 
            \Let{$\phantom{\left\{n_k \right\} }\mathllap{ \mathcal{S}}$}{$\mathcal{S} \bigcup_k \left\{ n_k, s_k\right\} $}
            \Let{$\phantom{\left\{n_k \right\} }\mathllap{ \mathcal{N}}$}{$\mathcal{N} \bigcup_k \left\{n_k \right\}$}
            \Let{$\phantom{\left\{n_k \right\} }\mathllap{\mathcal{T}}$}{subdivide($e_i, \mathcal{I}$)} 
            \Let{$\phantom{\left\{n_k \right\} }\mathllap{\mathcal{E}}$}{$\mathcal{E} \cup \mathcal{T}$}  
          \EndIf
        \EndFor
      \EndFor
      \State \Return{$\mathcal{W}, \mathcal{N}, \mathcal{E}$}
    \EndFunction
  \end{algorithmic}
\end{algorithm}


\end{document}

lo que da

ingrese la descripción de la imagen aquí

Respuesta1

Aquí hay una solución basada en el código publicado. Un enfoque completamente diferente tikzse encuentra enProblemas con líneas verticales en algorítmicox.

Para modificar el código actual es necesario utilizar reglas que no tengan una altura y profundidad fijas. Una forma de lograrlo es simplemente escribir \vrule. Sin embargo, debe garantizar tamaños mínimos y asegurarse de que el \lineskipmecanismo no separe las líneas resultantes. El siguiente código cubre todos sus ejemplos.

Salida de muestra

\documentclass{article}

\usepackage{mathtools}
\usepackage{amssymb}
\usepackage{amsbsy}

\usepackage[noend]{algpseudocode}
\usepackage{algorithm}
\usepackage{algorithmicx}

\usepackage{etoolbox}

\newcommand{\algruledefaultfactor}{.75}
\newcommand{\algstrut}[1][\algruledefaultfactor]{\vrule width 0pt
depth .25\baselineskip height #1\baselineskip\relax}
\newcommand*{\algrule}[1][\algorithmicindent]{\hspace*{.5em}\vrule\algstrut
\hspace*{\dimexpr#1-.5em}}

\makeatletter
\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
    % 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
}%

\patchcmd{\ALG@doentity}{\noindent\hskip\ALG@tlm}{\ALG@printindent}{}{\errmessage{failed to patch}}

\AtBeginEnvironment{algorithmic}{\lineskip0pt}

\newcommand*\Let[2]{\State #1 $\gets$ #2}
\newcommand*\Stateh{\State \algstrut[1]}

\begin{document}

\begin{algorithm}
  \caption{Arbitrary Algorithm}\label{IS2OSLS}
  \begin{algorithmic}[1]
    \Require A matrix $\mathbf{A}$ of size $m\times n$.
    \Ensure Something.
    \For{$i$ in $m$}
      \State{$\mathbf{X} \gets \begin{bmatrix*}[r]  \boldsymbol x_i  & \boldsymbol x_j & \ldots \end{bmatrix*}^\intercal $} \Comment{get coordinates}
      \For{$j$ in $n$}
        \If{$i=j$}
          \State Select a random action
          \Else
          \If{$i=j^3+1$}
            \State Stay silent
            \State $j \gets \begin{cases} a & b \\ c & d \end{cases} $
            \Else
            \State $i \gets \mathbf{J}^\intercal$
            \State Break
          \EndIf
        \EndIf
        \EndFor
    \EndFor
  \end{algorithmic}
\end{algorithm}

\begin{algorithm}
  \caption{Test 2
    \label{alg:interact}}
  \begin{algorithmic}[0]
    \Require{$\mathcal{M} := \left\{ \mathcal{N}, \mathcal{E} \right\}$ and  $\mathcal{G}$}
    \Function{test}{$\mathcal{M}, \mathcal{G}$}
      \Let{$\mathcal{S}$}{$\emptyset$}
      \For{$e_i \in \mathcal{E}$}
        \For{$g_i \in \mathcal{G}$}
          \Let{$\mathcal{I}$}{$e_i  \cap g_i$}
          \If{$\mathcal{I} \neq \emptyset $}
            \Let{$\left\{n_k \right\}$}{$\mathcal{I}$}
            \Let{$\hphantom{\left\{n_k \right\} }\mathllap{ \mathcal{S}}$}{$\mathcal{S} \bigcup_k \left\{ n_k, s_k\right\} $}
            \Let{$\hphantom{\left\{n_k \right\} }\mathllap{ \mathcal{N}}$}{$\mathcal{N} \bigcup_k \left\{n_k \right\}$}
            \Let{$\hphantom{\left\{n_k \right\} }\mathllap{\mathcal{T}}$}{subdivide($e_i, \mathcal{I}$)}
            \Let{$\hphantom{\left\{n_k \right\} }\mathllap{\mathcal{E}}$}{$\mathcal{E} \cup \mathcal{T}$}
            \EndIf
        \EndFor
      \EndFor
      \Stateh \Return{$\mathcal{W}, \mathcal{N}, \mathcal{E}$}
    \EndFunction
  \end{algorithmic}
\end{algorithm}

\end{document}

Reescribí el \algrulecomando, lo descomprimí de una caja, para que un aislado \vrulepueda llenar la altura y la profundidad de la línea actual. Luego se dibuja una regla de ancho cero para forzar que esa altura y profundidad sean razonables en líneas estándar. Esta regla está encapsulada en un nuevo comando \algstrut. Finalmente, algorithmicse parchea el entorno para \lineskipconfigurarlo en 0pt.

Si tiene dos líneas altas consecutivas, es posible que ahora se toquen, pero puede solucionar este problema agregando una regla de ancho cero de altura y profundidad adecuadas a su texto en estos casos únicos. Esto se puede hacer usando \algstrut[1]algún factor grande en la línea dada.

También resulta necesario tener un puntal más alto en \Statelas líneas, por lo que proporcioné un nuevo comando \Statehque incluye esto.

Por cierto, eliminé el código para la bmatrixalineación, ya que el mathtoolspaquete ahora proporciona bmatrix*una opción de alineación. También lo uso \hphantomen lugar de \phantomen tu ejemplo, ya que solo te interesa ajustar el espaciado horizontal.

información relacionada