为了学习 Tikz,我想重新创建众所周知的强化学习代理 -> 环境 -> 代理图。
这是我目前得到的:
\documentclass[border=0.2cm]{standalone}
\usepackage{microtype}
\usepackage{libertine}
\usepackage{tikz}
\usetikzlibrary{backgrounds, arrows, shapes, shapes.geometric, shapes.misc, math, positioning, calc}
\begin{document}
\begin{tikzpicture}
\tikzset{rect/.style={
rectangle,
draw
}}
\tikzset{single/.style={
->,
draw
}}
\tikzset{double/.style={to path={%
($(\tikztostart)+(1pt,0)$) |- ($(\tikztotarget)+(0,-1pt)$)
($(\tikztostart)+(-1pt,0)$) |- ($(\tikztotarget)+(0,1pt)$)
},
->,
draw
}}
% Nodes
\node[style=rect] (agent) at (0,0) {Agent};
\node[below=of agent, style=rect] (environment) {Environment};
\path[style=single] (agent.east) -| ++(1,0) node[style=rectangle] at ($(agent)!0.5!(environment)$) {$A_t$} |- (environment.east);
\draw (environment.west) to[double] (agent.west);
\end{tikzpicture}
\end{document}
两个问题:
- 我如何将 $A_t$ 节点定位到路径的右侧,并使其与代理节点和环境节点之间完全垂直?
- 我怎样才能将路径向左移动,稍微移出节点,然后向上移动,然后再向右转到代理节点?
答案1
欢迎来到 TeX.SX!我认为您的代码可以从一系列小改进中受益。
首先,你不需要在环境\tikzset
中添加多个宏tikzpicture
。相反,只需将定义放入环境的可选参数中即可tikzpicture
。
二、Ti钾Z 已经定义了double
您可能想要在此处使用的样式(当然,您需要以不同的方式调用您的样式,以免覆盖此预定义样式)。我认为更粗的箭头更合适。
第三,我认为定义箭头的坐标的定位可以简化,也可以统一,如下面的代码所示。我text depth
向文本节点添加了选项,使其高度相等。
最后,要将$A_t$
节点精确地放置在右侧并将其垂直对齐到其他两个节点之间,您应该了解以下内容:使用|-
(或-|
)标记时,您可以使用pos=0.5
来表示路径从垂直变为水平(或反之亦然)的坐标。此外,pos=0.25
(和pos=0.75
)表示从路径起点到此坐标的垂直(或水平)部分的中心。因此,使用此方法可以非常轻松地将节点放置$A_t$
在您想要的位置。
\documentclass[border=0.2cm]{standalone}
\usepackage{microtype}
\usepackage{libertine}
\usepackage{tikz}
\usetikzlibrary{positioning, arrows.meta}
\begin{document}
\begin{tikzpicture}[
>={Stealth[length=7pt]},
rect/.style={
rectangle,
draw,
text depth=0.1em
},
single arrow/.style={
->
},
double arrow/.style={
double,
double distance=1pt,
->
}]
% Nodes
\node[rect] (agent) at (0,0) {Agent};
\node[below=of agent, rect] (environment) {Environment};
\draw[single arrow] (agent) -- ++(1.5,0) |- node[pos=0.25, right] {$A_t$} (environment);
\draw[double arrow] (environment) -- ++(-1.5,0) |- (agent);
\end{tikzpicture}
\end{document}
由于您提供了预期结果的图像,我添加了此编辑建议。double
箭头的绘制方式与两个箭头非常不同。 此外,使用您的方法,您将无法简单地将两个箭头尖端附加到两条线上,并且绘制两个角周围的路径也很复杂。 因此,我建议您简单地绘制两个箭头并相应地移动箭头路径的坐标(以下代码可能不是实现此目的的最简单方法,但它展示了如何移动和对齐坐标的不同方法,可能会对您有所帮助):
\documentclass[border=0.2cm]{standalone}
\usepackage{microtype}
\usepackage{libertine}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}[
>=stealth,
rect/.style={
rectangle,
draw,
text depth=0.1em
}]
% Nodes
\node[rect] (agent) at (0,0) {Agent};
\node[below=of agent, rect] (environment) {Environment};
\draw[->, thick] (agent) -- ++(2.5,0) |-
node[pos=0.25, right] {$A_t$} (environment);
\coordinate (lower west) at ([shift={(-2cm, -2pt)}]environment.center);
\coordinate (upper west) at ([shift={(-2cm, 2pt)}]environment.center);
\draw[densely dotted] ([yshift=5pt]upper west) -- ([yshift=-5pt]lower west);
\draw[->] (environment.west |- upper west) -- (upper west)
node[midway, above] {$R_{t+1}$};
\draw[->, thick] (environment.west |- lower west) -- (lower west)
node[midway, below] {$S_{t+1}$};
\draw[->] (upper west) -- ++({-0.5cm + 2pt},0) |-
node[pos=0.25, right] {$R_t$} ([yshift=-2pt]agent.west);
\draw[->, thick] (lower west) -- ++({-0.5cm - 2pt},0) |-
node[pos=0.25, left] {$S_t$} ([yshift=2pt]agent.west);
\end{tikzpicture}
\end{document}