第一张图

第一张图

stackexchange 成员,我尝试过这样做,但不幸的是我做不到。这真的很简单。我找到了一些代码并尝试获得与我的类似的图片。

在此处输入图片描述

第二张图片是

在此处输入图片描述

非常感谢您的帮助,很抱歉占用了您的时间。问候。

答案1

一种选择是使用强大的forest包裹:

在此处输入图片描述

代码(带解释性注释):

\documentclass[varwidth=30cm,border=4pt]{standalone}
\usepackage{forest}
\usetikzlibrary{calc}

% The width of the [0,1] Intervals
\newlength\IntervalWd
\setlength\IntervalWd{5cm}

% Style for the upper labels in the intervals
\tikzset{
  numlabel/.style={above,pos=#1,font=\scriptsize,text=magenta}
}

% Command to draw the intervals
% Syntax
% \DrawInterval[base]{divisions}{lables}{position}
\newcommand\DrawInterval[4][2]{
  \draw[|-|] 
    (#4) node[below=3pt] {$0$} --
    ++(\IntervalWd,0pt) node[below=3pt] {$1$};
 \ifnum#2=1\relax
   \node[above,text=magenta,font=\scriptsize] at ([xshift=0.5\IntervalWd]#4) {1};
 \else   
  \foreach \Valor in {1,...,#2}
  {
    \draw 
      ([xshift=\Valor*(1/#2)*\IntervalWd] $ (#4) + (0,-2pt) $ ) --
      ++(0,4pt);
    \node[xshift=\Valor*(1/#2)*\IntervalWd,above,text=magenta,font=\scriptsize]
      at ([xshift=-0.5\Valor*(1/#2)*\IntervalWd]#4) 
      {\pgfmathprint{int(mod(\Valor-1,#1))}};
  }
  \foreach \Texto [count=\xi] in {#3}
  {
    \node[xshift=\xi*(1/#2)*\IntervalWd,anchor=base,yshift=-10pt,font=\scriptsize]
      at (#4) 
      {$\Texto$};
  }
  \fi  
}

\begin{document}

\begin{forest}
for tree={
  circle,
  fill,
  inner sep=1.5pt,
  parent anchor=south,
  s sep=20pt
},
delay={
  for tree={
    if n=1  
      {edge label={node[midway,left,text=magenta,font=\scriptsize] {$0$}}}
      {if n'=1  
        {edge label={node[midway,right,text=magenta,font=\scriptsize] {$1$}}}
        {}
      }
  },
}
[$\emptyset$,fill=none,name=level0
  [
    [ [,name=level3l] [] ]
    [ [] [] ]
  ]
  [,name=level1
    [ [] [] ]
    [,name=level2 [] [,name=level3] ]
  ]
]
% Auxiliary coordinates
\coordinate (aux1) at ([xshift=20pt]level3|-level0);
\coordinate (aux2) at ([xshift=2cm]level3|-level0);
\coordinate (aux3) at ([xshift=2cm+20pt]level3|-level0);
\coordinate (aux4) at ([xshift=-20pt]level3l|-level0);
% The level number
\foreach \Valor in {0,...,3}
{
  \node at  (aux4|-level\Valor) {\Valor};
}
% The arrows
\foreach \Valor in {0,...,3}
{
  \draw[<->,>=latex]
    (aux1|-level\Valor) -- (aux2|-level\Valor);
}
% The [0,1] intervals
%level0
\DrawInterval{1}{}{aux3|-level0}
%level1
\DrawInterval{2}{1/2}{aux3|-level1}
%level2
\DrawInterval{4}{1/4,1/2,3/4}{aux3|-level2}
%level2
\DrawInterval{8}{1/8,1/4,3/8,1/2,5/8,3/4,7/8}{aux3|-level3}
\end{forest}\par\bigskip

\begin{forest}
for tree={
  circle,
  fill,
  inner sep=1.5pt,
  parent anchor=south,
  s sep=15pt,
  l sep=30pt,
  if level=1{s sep=27pt}{}
},
delay={
  for tree={
    if n=1  
      {edge label={node[midway,left,text=magenta,font=\scriptsize] {$0$}}}
      {if n'=1  
        {edge label={node[midway,right,text=magenta,font=\scriptsize] {$2$}}}
        {edge label={node[midway,left,text=magenta,font=\scriptsize] {$1$}}}
      }
  },
}
[$\emptyset$,fill=none,name=level0
  [,edge={magenta}
    [,name=level2] [] [,edge={magenta}]
  ]
  [
    [] [] []
  ]
  [
    [] [] []
  ]
]
% Auxiliary coordinates
\coordinate (aux1) at ([xshift=-20pt] $ (level2|-level0)!0.5!(level2) $ );
\coordinate (aux2) at ([xshift=-2cm]aux1);
\coordinate (aux3) at ([xshift=-20pt]aux2);
\coordinate (aux4) at ([xshift=-\IntervalWd]aux3);
\draw[<->,>=latex]
  (aux1) -- (aux2);
\DrawInterval[3]{9}{,,1/3,,,2/3,,}{aux4}
\end{forest}

\end{document}

答案2

此版本使用实验性prooftrees软件包,该软件包已稍作更新以实现。

代码需要 0.08prooftrees或更高版本(包括在下面)。这需要forest因为包建立在 之上forest。它主要用于轻松排版逻辑树证明。其中一个关键问题是将行号对齐在左侧,将对齐方式对齐在右侧。在这里,右侧的空格用于绘制数字线,并使用添加到 的几个东西来调整行号,prooftrees以便轻松匹配问题中显示的样式。

第一张图

对齐树

代码

\documentclass[tikz,border=10pt]{standalone}
\usepackage{prooftrees}% v 0.08
\usetikzlibrary{arrows.meta, positioning}
\begin{document}
  \renewcommand\linenumberstyle[1]{#1}% default uses dots after the number
  \forestset{
    my label/.style n args=2{
      edge label={node [midway, text=red, font=\scriptsize, #1] {$#2$}}
    },
  }
  \begin{prooftree}{
      zero start,% default starts numbering with 1
      line justifications,% justifications must be explicitly enabled as their content is not specified directly
      just format/.style={% this is used to draw the arrows and number lines on the right (where the justifications for inferences would go in a tree proof in logic)
        before drawing tree={
          tikz/.wrap 2 pgfmath args={
            [font=\scriptsize]
            \draw [{Stealth[]}-{Stealth[]}] (!<.base east) +(1.5mm,0) -- (.base) -- ++(10mm,0) coordinate (c);
            \draw [font=\small]
               [{Bar[width=10pt]}-{Bar[width=10pt]}] (c) ++(5pt,0) node (n1) [below=5pt] {$0$} -- ++(50mm,0) node (n2) [below=5pt] {$1$};
            \ifnum##2>1
            \path (n1 |- c) -- (n2 |- c) node [pos=.5/##2, above, text=red] {0} foreach \i [evaluate=\i as \ieval using {int(mod(\i,2))}] in {1,...,##1} { node [pos={(\i+.5)/##2}, above, text=red] {\ieval} node (nn\i) [pos=\i/##2, below=2.5pt] {$\frac{\i}{##2}$}};
              \foreach \i in {1,...,##1} \draw (c -| nn\i) +(0,2.5pt) -- +(0,-2.5pt);
            \fi
          }{int((2^(level()-1))-1)}{int(2^(level()-1))},
        }
      },
      for tree={% this sets up the main tree, rooted at the empty set symbol
        math content,
        if level=1{}{
          circle,
          fill,
          minimum size=2.5pt,
          inner sep=0pt,
          outer sep=0pt,
          if n=1{% add the red labels on the sides automatically
            if level=2{
              my label={above left}{0}
            }{
              my label={left}{0}
            },
          }{
            if n'=1{
              if level=2{
                my label={above right}{1}
              }{
                my label={right}{1}
              },
            }{}
          }
        },
        if level=0{% increase the separation a bit - necessary to stop squishing with the additional level added here for demonstration purposes
          for descendants={s sep+=5pt},
        }{},
      }
    },
    [\emptyset% this is the root of the main tree
      [[[[][]][[][]]][[[][]][[][]]]]% main left branch
      [[[[][]][[][]]][[[][]][[][]]]]% main right branch
    ]
  \end{prooftree}
\end{document}

请注意,在第一个可见级别之上还有一个额外的不可见级别。这些都是自动创建的。如果您想要使用级别信息执行操作,则只需知道这一点。例如,在下面的代码中,我使用此信息来创建数字线。因此,空集符号在级别 1 很重要,forest即使就图表而言它处于级别 0。

包裹

将以下内容保存为prooftrees.sty并将其粘贴在与文件相同的目录中.tex

%% Copyright 2015 cfr
%%
\ProvidesPackage{prooftrees}[2015/07/20 v0.08 prooftrees]
\RequirePackage{forest}                                                                                                                    
\newcounter{prooftree@countlevels}% count the levels in the proof tree                                                                     
\setcounter{prooftree@countlevels}{0}                                                                                                      
\newcount\prooftree@lcount% count the line numbers (on the left)                                                                           
\newcount\prooftree@jcount% count the justifications (on the right)                                                                        
\newcount\prooftree@linenoshift% adjustment for line numbering
\newcommand*\linenumberstyle[1]{#1.}
\forestset{
  declare boolean={numbers}{0},% line numbering
  declare boolean={justifiers}{0},% line justifications
  declare boolean={verticals}{0},% single branches
  grouped/.style={% this adjusts the alignment of line numbers and justifications when some levels of the tree are grouped together either whenever the number of children is only 1 or by applying the grouped style to particular nodes when specifying the tree
        before computing xy={
          l=\baselineskip,
          if={\forestove{numbers}==1}{
                if={\forestove{justifiers}==1}{
                  node walk={
                        every step/.style={l=\baselineskip},
                        after walk/.style={l=\baselineskip},
                        name/.wrap pgfmath arg={just ##1}{level()},
                        name/.wrap pgfmath arg={line no ##1}{level()},
                  },
                }{
                  node walk={
                        after walk/.style={l=\baselineskip},
                        name/.wrap pgfmath arg={line no ##1}{level()},
                  },
                },
          }{
                if={\forestove{justifiers}==1}{
                  node walk={
                        after walk/.style={l=\baselineskip},
                        name/.wrap pgfmath arg={just ##1}{level()}
                  },
                }{},
          },
        },
        no edge,
  },
  close/.style={
        label={[yshift=2.5pt]below:$\otimes$},
  },
  line no/.style={% creates the line numbers on the left
        no edge,
        before typesetting nodes={% page 51
          TeX={\advance\prooftree@lcount1},
          content/.expanded/.wrap pgfmath arg={\linenumberstyle{##1}}{int(\linecounter+\the\prooftree@linenoshift)},% content i.e. the line number
          name/.expanded={line no \the\prooftree@lcount},% name them so they can be moved later
          if={\the\prooftree@lcount>2}{% the initial location of most line numbers is incorrect and they must be moved
                for previous={% move the line number below the previous line number
                  append/.expanded={line no \the\prooftree@lcount}
                },
          }{},
        },
  },
  line justification/.style={% creates the justifications on the right but does not yet specify any content
        anchor=base west,
        no edge,
        before typesetting nodes={% page 51
          TeX={\advance\prooftree@jcount1},
          name/.expanded={just \the\prooftree@jcount},% name them so they can be moved
          if={\the\prooftree@jcount>2}{% correct the location as for the line numbers (cf. line no style)
                for previous={
                  append/.expanded={just \the\prooftree@jcount}
                },
          }{},
        },
  },
  line numbering/.style={
        for tree={numbers},
  },
  no line numbering/.style={
        for tree={not numbers},
  },
  line numbering shift/.style={
        TeX={\advance\prooftree@linenoshift#1},
  },
  zero start/.style={
        line numbering shift=-1,
  },
  line justifications/.style={
        for tree={justifiers},
  },
  no line justifications/.style={
        for tree={not justifiers},
  },
  single branches/.style={
        for tree={verticals},
  },
  no single branches/.style={
        for tree={not verticals},
  },
  to prove/.style={
        before typesetting nodes={
          if level=0{
                content={#1},
                phantom=false,
          }{}
        }
  },
  proof tree/.style={
        for tree={
          parent anchor=south,
          line numbering,
          delay={
                where content={}{
                  shape=coordinate,
                }{}
          },
        },
        where level=0{
          for children={
                no edge,
          },
          delay={
                if content={}{phantom}{},
                if={(\forestove{numbers}==1) || (\forestove{justifiers}==1)}{% count the levels if necessary
                  for descendants={
                        if={level()>\value{prooftree@countlevels}}{
                          TeX={
                                \stepcounter{prooftree@countlevels}
                          },
                        }{},
                  },
                }{},
                if={(\forestove{numbers}==1)}{% create the line numbers if appropriate
                  prepend={
                        [,
                          line no,
                          line no format,
                          repeat={\value{prooftree@countlevels}-1}{% most are created in the wrong place but line no moves them later
                                delay n={\the\prooftree@lcount}{
                                        append={[, line no, line no format]}
                                },
                          }
                        ]
                  },
                }{},
                if={(\forestove{justifiers}==1}{% create the nodes which will hold the justifications, if required
                  append={
                        [,
                          fit=rectangle,
                          just format,
                          line justification,
                          repeat={\value{prooftree@countlevels}-1}{% most are created in the wrong place but line justification moves them later
                                delay n={\the\prooftree@jcount}{
                                  append={[, line justification, just format]}
                                },
                          }
                        ]
                  }
                }{},
          },
        }{
          delay={
                if={(\forestove{verticals}==0}{% automatically group lines if not using single branches
                  if n children=1{
                        for children={
                          if ={(\forestove{verticals}==0}{
                                grouped
                          }{},
                        }
                  }{},
                }{},
          }
        },
        before packing={
          for tree={
                tier/.wrap pgfmath arg={tier ##1}{level()},
          },
        },
  },
  just/.style={
        if={\forestove{justifiers}==0}{
          for root={
                line justifications,
          },
        }{},
          before packing={% puts the content of the justifications into the empty justification nodes on the right; because this is done late, the nodes need to be typeset again
                for={name/.wrap pgfmath arg={just ##1}{level()}}{
                  content={#1},
                  typeset node
                },
          }
  },
  toing/.style={% this is here so I can easily override no edge when to line={} is used
        edge path={
          \noexpand\path [draw, \forestoption{edge}] (!u.parent anchor) -- (.child anchor)\forestoption{edge label};
        },
  },
  to line/.style={% this option is intended for use with justifications and, although it should not give an error, it will have no effect in other cases (There is simply no reason to typeset a proof with this if not giving justifications, that I can think of)
        if={#1>\value{prooftree@countlevels}}{% ensure that we get enough lines in the tree since #1 may well specify a line which would not otherwise exist
          TeX={
                \setcounter{prooftree@countlevels}{#1}
          },
        }{},
        if={#1>level()}{% only try to move the node if the target line number exceeds the current level
          if={\forestove{justifiers}==0}{% don't do anything if there are no justifications - there is no point in moving things in such a case
          }{
                if={\forestove{verticals}==0}{% if no single branches, get the vertical alignment from the correctly aligned line justification
                  before drawing tree={
                        y/.wrap pgfmath arg={##1}{y("!name={just #1}")},
                        toing
                  },
                }{
                  before packing={% if single branches, a simple tier alignment suffices
                        tier=tier #1,
                  },
                },
          },
        }{},
  },
  just to line/.style n args=2{
        if={\forestove{justifiers}==0}{
          for root={
                line justifications,
          },
        }{},
        if={#1>\value{prooftree@countlevels}}{% make sure the tree contains enough lines since #1 may exceed the total line count otherwise
          TeX={
                \setcounter{prooftree@countlevels}{#1}
          },
        }{},
        if={#1>level()}{% only if the target line number exceeds the current level
          before packing={
                for={name={just #1}}{% specify the content of the target line justification and, because this is done late, typeset the node again
                  content={#2},
                  typeset node
                },
          }
        }{% do nothing if the target line number is less than the current level
          if={#1==level()}{% only if the target line number equals the current level
                just=#2,
          }{},
        },
  },
  just format/.style={},
  line no format/.style={},
}
\newcommand*\linecounter{\linecountformat{\the\prooftree@lcount}}
\newcommand*\linecountformat[1]{#1.}
\environbodyname\prooftreebody
\bracketset{action character=@}
\NewEnviron{prooftree}[1]{% \forest/\endforest from egreg's answer at http://tex.stackexchange.com/a/229608/
  \forest
        proof tree,
        #1,
        [@\prooftreebody]
  \endforest}
\endinput
%% end prooftrees.sty

相关内容