我尝试得到同样的想法布朗运动 3D 正态分布但用重组二项树代替布朗运动,并且每个节点都有相应的二项分布。这个想法是为了展示二项树如何收敛到正态分布。下图是 2D(不太清晰)版本。如何让二项树在一个平面上生长,并看到二项分布收敛到正态分布?
在二项分布我们得到 binom 函数
declare function={binom(\k,\n,\p)=\n!/(\k!*(\n-\k)!)*\p^\k*(1-\p)^(\n-\k);}
从重组二项式树我们得到了递归二叉树的思想。然而我甚至无法给出一个 MWE。
答案1
从@marmot 的回答开始,但我不太了解坐标和-0.5
我需要在x
坐标上进行的转变。
\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{3d}
\usetikzlibrary{fpu}
\usepackage{xintexpr}
% 8 digits precision is enough
\xintDigits := 8;
% I don't like the order of variables but I picked it up from OP
\xintdeffloatfunc binom(k, n, p) := binomial(n, k)*p^k*(1-p)^(n-k);
\begin{document}
\tdplotsetmaincoords{110}{-30}
\begin{tikzpicture}[binom tree/.style={insert path={%
foreach \X in {1,...,#1}
{foreach \Y in {1,...,\X} {(\X,\Y-\X/2) -- (\X+1,\Y+1/2-\X/2)
(\X,\Y-\X/2) -- (\X+1,\Y-1/2-\X/2)} }}},tdplot_main_coords]
\begin{scope}[canvas is xy plane at z=0,scale=0.5]
\draw[blue,binom tree=15];
\end{scope}
\tdplotsetrotatedcoords{0}{0}{0}
\begin{scope}[tdplot_rotated_coords]
\xintFor* #1 in {\xintSeq{2}{16}}:
{
\begin{scope}[canvas is yz plane at x=#1/2, scale=0.5]
\draw[red,thick] plot[smooth] coordinates {\xintthecoords
\xintfloatexpr seq((x-#1/2+0.5,8*binom(x, #1, 0.5)), x=0..#1)\relax};
\end{scope}
}
\end{scope}
\end{tikzpicture}
\end{document}
我更了解坐标。我认为使用重新缩放的条形图并考虑到“ecart 类型”更接近原始问题。(但我保留了 marmot 答案中的 3D 设计)。
\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{3d}
\usetikzlibrary{fpu}
\usepackage{xintexpr}
% 8 digits precision is enough
\xintDigits := 8;
% I don't like the order of variables but I picked it up from OP
\xintdeffloatfunc binom(k, n, p) := binomial(n, k)*p^k*(1-p)^(n-k);
\begin{document}
\tdplotsetmaincoords{110}{-30}
\begin{tikzpicture}[binom tree/.style={insert path={%
foreach \X in {1,...,#1}
{foreach \Y in {1,...,\X} {(\X,\Y-\X/2) -- (\X+1,\Y+1/2-\X/2)
(\X,\Y-\X/2) -- (\X+1,\Y-1/2-\X/2)} }}},tdplot_main_coords]
\begin{scope}[canvas is xy plane at z=0]
\draw[blue,binom tree=48];
\end{scope}
\tdplotsetrotatedcoords{0}{0}{0}
\begin{scope}[tdplot_rotated_coords]
\xintFor* #1 in {\xintSeq{0}{48}}:
{
\begin{scope}[canvas is yz plane at x=#1+1]
% ybar means in z direction here, as horizontal coordinate is y
\draw[red,thick] plot[ybar] coordinates {\xintthecoords
\xintfloatexpr subs(
seq((y-#1/2+0.5,A*binom(y, #1, 0.5)), y=0..#1)
,A=sqrt(#1))\relax};
\end{scope}
}
\end{scope}
\end{tikzpicture}
\end{document}
以下是
\begin{tikzpicture}[scale=0.5,binom tree/.style={insert path={%
foreach \X in {1,...,#1}
{foreach \Y in {1,...,\X} {(\X,\Y-\X/2) -- (\X+1,\Y+1/2-\X/2)
(\X,\Y-\X/2) -- (\X+1,\Y-1/2-\X/2)} }}},tdplot_main_coords]
\begin{scope}[canvas is xy plane at z=0]
\draw[blue,binom tree=96];
\end{scope}
\tdplotsetrotatedcoords{0}{0}{0}
\begin{scope}[tdplot_rotated_coords]
\xintFor* #1 in {\xintSeq[6]{0}{96}}:
{
\begin{scope}[canvas is yz plane at x=#1+1]
% ybar means in z direction here, as horizontal coordinate is y
\fill[red,thick] plot[ybar] coordinates {\xintthecoords
\xintfloatexpr subs(
seq((y-#1/2+0.5,A*binom(y, #1, 0.5)), y=0..#1)
,A=4*sqrt(#1))\relax};
\end{scope}
}
\end{scope}
\end{tikzpicture}
大部分 (超过 3/4) 的时间都花在蓝色画布上。
这里是p=0.25
。
\begin{scope}[tdplot_rotated_coords]
\xintFor* #1 in {\xintSeq[6]{0}{96}}:
{
\begin{scope}[canvas is yz plane at x=#1+1]
% ybar means in z direction here, as horizontal coordinate is y
\fill[red,thick] plot[ybar] coordinates {\xintthecoords
\xintfloatexpr subs(
seq((y-#1/2+0.5,A*binom(y, #1, 0.25)), y=0..#1)
,A=4*sqrt(#1))\relax};
\end{scope}
}
\end{scope}
完整代码和动画(p=0.25
)
\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{3d}
\usetikzlibrary{fpu}
\usepackage{xintexpr}
% 8 digits precision is enough
\xintDigits := 8;
% I don't like the order of variables but I picked it up from OP
\xintdeffloatfunc binom(k, n, p) := binomial(n, k)*p^k*(1-p)^(n-k);
\begin{document}
\tdplotsetmaincoords{110}{-30}
\xintFor* #1 in {\xintSeq[3]{2}{50}}:
{
\begin{tikzpicture}[scale=0.5,binom tree/.style={insert path={%
foreach \X in {1,...,#1}
{foreach \Y in {1,...,\X} {(\X,\Y-\X/2) -- (\X+1,\Y+1/2-\X/2)
(\X,\Y-\X/2) -- (\X+1,\Y-1/2-\X/2)} }}},tdplot_main_coords]
% \xintifForLast {
\begin{scope}[canvas is xy plane at z=0]
\draw[very thin] (1,-25.5)--(51,-25.5) -- (51,25.5)-- (1, 25.5) -- cycle;
%\draw[blue, very thick] (0,0)--(33,-16.5) -- (33,16.5)-- cycle;
% \draw[blue,binom tree=32];
% \draw[blue,binom tree=96];
\draw[blue, binom tree=#1];
\draw (#1+1, 25.5) node [right, scale=2] {\smash{\rlap{$#1$}}};
\end{scope}
% }{}
\tdplotsetrotatedcoords{0}{0}{0}
\begin{scope}[tdplot_rotated_coords]
\begin{scope}[canvas is yz plane at x=#1+1]
% ybar means in z direction here, as horizontal coordinate is y
\fill[red,thick] plot[ybar] coordinates {\xintthecoords
\xintfloatexpr subs(
seq((y-#1/2+0.5,A*binom(y, #1, 0.25)), y=0..#1)
,A=4*sqrt(#1))\relax};
\end{scope}
\end{scope}
\end{tikzpicture}
}
\end{document}
执行pdflatex
此操作然后
convert -verbose -delay 75 -loop 0 -density 100 binomialplotV.pdf binomialplotV.gif
注意p=0.15, 0.5, 0.85
,中心情况更加分散,这是正常的,因为它的方差较大。
(放大时显示效果更佳)
答案2
这是一个快速写成的提案,其中我用高斯分布来近似二项分布。
\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{3d}
\begin{document}
\tdplotsetmaincoords{110}{-30}
\begin{tikzpicture}[binom tree/.style={insert path={%
foreach \X in {1,...,#1}
{ foreach \Y in {1,...,\X} {(\X,\Y-\X/2) -- (\X+1,\Y+1/2-\X/2)
(\X,\Y-\X/2) -- (\X+1,\Y-1/2-\X/2)} }}},tdplot_main_coords]
\begin{scope}[canvas is xy plane at z=0,scale=0.5]
\draw[blue,binom tree=15];
\end{scope}
\tdplotsetrotatedcoords{0}{0}{0}
\begin{scope}[tdplot_rotated_coords,declare function={gauss(\x,\y,\z)=1/(\y*sqrt(2*pi))*exp(-((\x-\z)^2)/(2*\y^2));}]
\begin{scope}[canvas is yz plane at x=4,scale=0.5]
\draw[red,thick] plot[variable=\x,domain=-4:4,samples=51,smooth] (\x+0.5,{6*gauss(\x,1,0)});
\end{scope}
\begin{scope}[canvas is yz plane at x=8,scale=0.5]
\draw[red,thick] plot[variable=\x,domain=-8:8,samples=51,smooth] (\x+0.5,{6*gauss(\x,2,0)});
\end{scope}
\end{scope}
\end{tikzpicture}
\end{document}
利用该fpu
库您可以绘制一些二项分布,但不幸的是,它并不能带给您很大的帮助。
\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{3d}
\usetikzlibrary{fpu}
\begin{document}
\tdplotsetmaincoords{110}{-30}
\begin{tikzpicture}[binom tree/.style={insert path={%
foreach \X in {1,...,#1}
{ foreach \Y in {1,...,\X} {(\X,\Y-\X/2) -- (\X+1,\Y+1/2-\X/2)
(\X,\Y-\X/2) -- (\X+1,\Y-1/2-\X/2)} }}},tdplot_main_coords]
\begin{scope}[canvas is xy plane at z=0,scale=0.5]
\draw[blue,binom tree=15];
\end{scope}
\tdplotsetrotatedcoords{0}{0}{0}
\begin{scope}[tdplot_rotated_coords,declare
function={gauss(\x,\y,\z)=1/(\y*sqrt(2*pi))*exp(-((\x-\z)^2)/(2*\y^2));},
declare function={binom(\k,\n,\p)=\n!/(\k!*(\n-\k)!)*\p^\k*(1-\p)^(\n-\k);}]
\begin{scope}[canvas is yz plane at x=4,scale=0.5]
\pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}
\pgfmathsetmacro{\Z}{4*binom(0,8,0.5)}
\xdef\lstX{(-3.5,\Z)}
\foreach \X [count=\Y] in {1,...,8}
{
\pgfmathsetmacro{\Z}{4*binom(\X,8,0.5)}
\xdef\lstX{\lstX (\X-3.5,\Z)}
}
\draw[red,thick] plot[smooth] coordinates {\lstX};
\end{scope}
\begin{scope}[canvas is yz plane at x=6,scale=0.5]
% \pgfmathsetmacro{\Z}{binom(1,12,0.5)}
% \xdef\lstX{(-6,\Z)}
% \foreach \X [count=\Y] in {1,...,12}
% {
% \pgfmathsetmacro{\Z}{binom(\X,12,0.5)}
% \typeout{\Z}
% \xdef\lstX{\lstX (\X-6,\Z)}
% }
% \draw[red,thick] plot[smooth] coordinates {\lstX};
\end{scope}
\end{scope}
\end{tikzpicture}
\end{document}
解决这个问题的最可能的方法是使用伽马函数。但我不确定这是否可以与高斯区分开来。