在 tikz 中根据转换矩阵绘制有向图

在 tikz 中根据转换矩阵绘制有向图

我想在 tikz 中绘制一个有向图,从转换矩阵开始,如下所示。位置 ij 中的“1”表示状态 i 导致状态 j。

[0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0;
 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0;
 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0;
 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0;
 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0;
 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0;
 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0;
 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0;
 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0]

从这个(或类似的东西)开始,我想在 tikz 中自动生成有向图。你能告诉我如何实现这个目标吗?

编辑:理想情况下,我希望节点的位置与此类似https://r-graphics.org/R-Graphics-Cookbook-2e_files/figure-html/FIG-MISCGRAPH-GRAPH-DIRECTED-1.png

在此处输入图片描述

答案1

也许这可以作为一个起点?我不知道把节点放在哪里,所以我不确定。无论如何,这是我的想法:

\documentclass[tikz,border=2mm]{standalone}
\tikzset{my node/.style={draw,circle,minimum size=0.75cm}}

\begin{document}
\begin{tikzpicture}
\def\nn{5} % number of nodes
\def\r{3}  % radius
\foreach\i in {1,...,\nn}
  \node[draw,circle] (\i) at ({360/\nn*(\i-1)}:\r) {\i};
\foreach[count=\j]\i in {% Matrix:
1,1,1,0,0,
0,1,0,0,1,
1,1,0,1,1,
0,0,0,1,0,
1,0,0,1,0
}
{
  \ifnum\i=1
    \pgfmathtruncatemacro\row{div(\j-1,\nn)+1}
    \pgfmathtruncatemacro\col{mod(\j-1,\nn)+1}
    \ifnum\row=\col% same initial and final state
      \pgfmathtruncatemacro\a{360/\nn*(\row-1)+30}
      \pgfmathtruncatemacro\b{\a-60}
      \draw[->] (\row.\a) to[out=\a,in=\b,looseness=4] (\row.\b);
    \else
      \draw[->] (\row) -- (\col);
    \fi
  \fi
}
\end{tikzpicture}
\end{document}

输出结果如下:

在此处输入图片描述

答案2

代码

\documentclass[tikz]{standalone}
\usetikzlibrary{
  arrows.meta,     % for pretty arrows
  graphs,          % for \graph syntax
  graphdrawing}    % for algorithms → LuaLaTeX
\usegdlibrary{force}
\newcommand*\foreachListPlusOneUntil[2]{%
  \ifnum#1<#2 \the\numexpr#1+1\relax,...,#2\fi}
\tikzset{
  weights/matrix/.style={
    /utils/exec=\def\tikzweightrow{0},
    /utils/rows/.style={
      /utils/exec=\def\tikzweightcolumn{0}%
                  \edef\tikzweightrow{\the\numexpr\tikzweightrow+1\relax},
      /utils/cols/.estyle={
        /utils/exec=\edef\noexpand\tikzweightcolumn
          {\noexpand\the\numexpr\noexpand\tikzweightcolumn+1\relax},
        /tikz/weights/weight \tikzweightrow-\noexpand\tikzweightcolumn/.initial
          ={####1}},
      /utils/cols/.list={##1}},
    /utils/rows/.list={#1}}}
\begin{document}
\tikz[
  >=Stealth,
  weights/matrix={
    {0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0}}]
\graph [
  spring electrical Walshaw 2000 layout,
  node distance=2cm,
  self edge/.style={/tikz/style/.expanded={%
    \ifnum\pgfkeysvalueof{/tikz/weights/weight #1-#1}=1 double\fi}},
  edge 0-1/.style 2 args={parse={#1 <-  #2[self edge=#2]}},
  edge 1-0/.style 2 args={parse={#1  -> #2[self edge=#2]}},
  edge 1-1/.style 2 args={parse={#1 <-> #2[self edge=#2]}},
  nodes={circle, draw, text width=width("00"), align=center},
]{
  \foreach \row in {1,...,\tikzweightrow} {
    \row[self edge=\row],
    \foreach[expand list]\col in {\foreachListPlusOneUntil\row\tikzweightrow}{
      [edge \pgfkeysvalueof{/tikz/weights/weight \row-\col}-%
            \pgfkeysvalueof{/tikz/weights/weight \col-\row}/.try={\row}{\col}]
    }
  }
};
\end{document}

输出

在此处输入图片描述

相关内容