5

I found here a possibility for stating linear programs. But if I have several LPs and change for example one of the constraints, the positions of the captions get lost - only the last of them is correct. Is it possible to fix it? Or even better: how can I write the caption next to the LP (just like for the first LP in the picture)?

Here's my code:

\documentclass{scrbook}

\usepackage{mathtools,zref-savepos}

\parindent0mm

\begin{document}

    \zsavepos{text-left-margin}%

    Heres is some text. 

    \begin{alignat*}{4}
    & \zsavepos{top-lp}\text{min} \quad \mathrlap{\sum_{a \in A} k_a u_a + \sum_{r \in R} \sum_{a \in A} f_a^r y_a^r} \\
    & \text{s.t.} \quad & \smashoperator{\sum_{a \in \delta_i^+}} y_a^r - \smashoperator{\sum_{a \in \delta_i^-}} y_a^r
    &= t & \quad & (\forall r \in R)(\forall i \in V) \\
    & & y_a^r &\leq u_a && (\forall r \in R)(\forall a \in A) \\
    & &   u_a &\in \{0,1\} && (\forall a \in A) \\
    & & y_a^r &\in [0,1] && (\forall r \in R)(\forall a \in A)\zsavepos{bottom-lp}
    \raisebox{0.5\dimexpr\zposy{top-lp}sp-\zposy{bottom-lp}sp}[0pt][0pt]{%
        \makebox[0pt][r]{\rlap{(LP)}\hspace*{\dimexpr\zposx{bottom-lp}sp-\zposx{text-left-margin}sp}}}
    \end{alignat*}

    Text...

    \begin{alignat*}{4}
    & \zsavepos{top-lp}\text{min} \quad \mathrlap{\sum_{a \in A} k_a u_a + \sum_{r \in R} \sum_{a \in A} f_a^r y_a^r} \\
    & \text{s.t.} \quad & \smashoperator{\sum_{a \in \delta_i^+}} y_a^r - \smashoperator{\sum_{a \in \delta_i^-}} y_a^r
    &= t & \quad & (\forall r \in R) \\
    & & y_a^r &\leq u_a && (\forall r \in R) \\
    & &   u_a &\in \{0,1\} && (\forall a \in A) \\
    & & y_a^r &\in [0,1] && (\forall r \in R)\zsavepos{bottom-lp}
    \raisebox{0.5\dimexpr\zposy{top-lp}sp-\zposy{bottom-lp}sp}[0pt][0pt]{%
        \makebox[0pt][r]{\rlap{(LP)}\hspace*{\dimexpr\zposx{bottom-lp}sp-\zposx{text-left-margin}sp}}}
    \end{alignat*}

    Text...

    \begin{alignat*}{4}
    & \zsavepos{top-lp}\text{min} \quad \mathrlap{\sum_{a \in A} k_a u_a + \sum_{r \in R} \sum_{a \in A} f_a^r y_a^r} \\
    & \text{s.t.} \quad & \smashoperator{\sum_{a \in \delta_i^+}} y_a^r - \smashoperator{\sum_{a \in \delta_i^-}} y_a^r
    &= abc & \quad &  \\
    & & y_a^r &\leq u_a &&  a \in A\\
    & &   u_a &\in \{0,1\} && \\
    & & y_a^r &\in [0,1] && \zsavepos{bottom-lp}
    \raisebox{0.5\dimexpr\zposy{top-lp}sp-\zposy{bottom-lp}sp}[0pt][0pt]{%
        \makebox[0pt][r]{\rlap{(LP)}\hspace*{\dimexpr\zposx{bottom-lp}sp-\zposx{text-left-margin}sp}}}
    \end{alignat*}

\end{document}

And this is the result:

incorrectLPs

Rorschach
  • 325

1 Answers1

2

zref's \zsavepos{<label>} works in a very similar to \label{<label>}, which requires you to have a unique <label> for each call. You are using the same, which is the cause for your varied alignments.

In the example below, each LP was given a unique top top-lp-? and bottom bottom-lp-? label:

enter image description here

\documentclass{scrbook}

\usepackage{mathtools,zref-savepos}

\setlength{\parindent}{0mm}

\begin{document}

\zsavepos{text-left-margin}%
Here is some text\ldots
\begin{alignat*}{4}
  & \zsavepos{top-lp-1}\text{min} \quad \mathrlap{\sum_{a \in A} k_a u_a + \sum_{r \in R} \sum_{a \in A} f_a^r y_a^r} \\
  & \text{s.t.} \quad & \smashoperator{\sum_{a \in \delta_i^+}} y_a^r - \smashoperator{\sum_{a \in \delta_i^-}} y_a^r
  &= t & \quad & (\forall r \in R)(\forall i \in V) \\
  & & y_a^r &\leq u_a && (\forall r \in R)(\forall a \in A) \\
  & &   u_a &\in \{0,1\} && (\forall a \in A) \\
  & & y_a^r &\in [0,1] && (\forall r \in R)(\forall a \in A)\zsavepos{bottom-lp-1}
  \raisebox{0.5\dimexpr\zposy{top-lp-1}sp-\zposy{bottom-lp-1}sp}[0pt][0pt]{%
    \makebox[0pt][r]{\rlap{(LP)}\hspace*{\dimexpr\zposx{bottom-lp-1}sp-\zposx{text-left-margin}sp}}}
\end{alignat*}

Text\ldots
\begin{alignat*}{4}
  & \zsavepos{top-lp-2}\text{min} \quad \mathrlap{\sum_{a \in A} k_a u_a + \sum_{r \in R} \sum_{a \in A} f_a^r y_a^r} \\
  & \text{s.t.} \quad & \smashoperator{\sum_{a \in \delta_i^+}} y_a^r - \smashoperator{\sum_{a \in \delta_i^-}} y_a^r
  &= t & \quad & (\forall r \in R) \\
  & & y_a^r &\leq u_a && (\forall r \in R) \\
  & &   u_a &\in \{0,1\} && (\forall a \in A) \\
  & & y_a^r &\in [0,1] && (\forall r \in R)\zsavepos{bottom-lp-2}
  \raisebox{0.5\dimexpr\zposy{top-lp-2}sp-\zposy{bottom-lp-2}sp}[0pt][0pt]{%
    \makebox[0pt][r]{\rlap{(LP)}\hspace*{\dimexpr\zposx{bottom-lp-2}sp-\zposx{text-left-margin}sp}}}
\end{alignat*}

Text\ldots
\begin{alignat*}{4}
  & \zsavepos{top-lp-3}\text{min} \quad \mathrlap{\sum_{a \in A} k_a u_a + \sum_{r \in R} \sum_{a \in A} f_a^r y_a^r} \\
  & \text{s.t.} \quad & \smashoperator{\sum_{a \in \delta_i^+}} y_a^r - \smashoperator{\sum_{a \in \delta_i^-}} y_a^r
  &= abc & \quad &  \\
  & & y_a^r &\leq u_a &&  a \in A\\
  & &   u_a &\in \{0,1\} && \\
  & & y_a^r &\in [0,1] && \zsavepos{bottom-lp-3}
  \raisebox{0.5\dimexpr\zposy{top-lp-3}sp-\zposy{bottom-lp-3}sp}[0pt][0pt]{%
    \makebox[0pt][r]{\rlap{(LP)}\hspace*{\dimexpr\zposx{bottom-lp-3}sp-\zposx{text-left-margin}sp}}}
\end{alignat*}

\end{document}

Note that horizontal placement is relative to the text-left-margin label, which is set to the left of the text block. If you want the "caption" (LP) to be closer to the actual LP construction, then you can place your reference labels in different locations and perform calculations accordingly.

Werner
  • 603,163
  • EDIT: There's still a problem if you use "\zsavepos{text-left-margin}" for the positioning of the "caption". If you write another LP on the second page, then the captions will be indeed one above the other but that doesn't go together with the page style - i think the reason for this is the document class, isn't it? – Rorschach Dec 07 '15 at 20:27
  • @Rorschach: The text-left-margin label is set on a specific page, and gives a way to identify the left-most margin of that page. If your class issues a two-side option, then it may be that you have a different left/right margin depending on whether you're on an even/odd page. Based on that you may have to create a separate text-left-margin-even and text-left-margin-odd marker, and use the appropriate one for that page. – Werner Dec 07 '15 at 21:19
  • LaTeX is new to me, sorry for my questions. How do you create those markers? And after creating those, did I get it right that I have to check first on which side (even or odd) the LP is written? Isn't there a possibility for automation? Something like if (currentPage = odd) then use text-left-margin-odd, else use text-left-margi n-even? I saw if-statements in LaTeX before, that's the reason I ask. – Rorschach Dec 08 '15 at 22:23
  • @Rorschach: Sure, you can automate some of the functionality, but it will surely outweigh the benefit from fixing such things at the end of the document creation (in my opinion). – Werner Dec 09 '15 at 03:52