节点图的最少代码?

节点图的最少代码?

所以我想做一个这样的图表:

https://en.m.wikipedia.org/wiki/Dijkstra%27s_algorithm#/media/File%3ADijkstra_Animation.gif

对于 djikstras 算法。不打算在 latex 中将其制作成动画,而希望制作成像这样的静态图像,但所有数字都在线上等等...

我已经在 tikz 中完成了一个,但代码太大,难以管理。有没有其他软件包可以让我以更少的代码绘制这样的节点图,从而更易于管理和更改图表?

代码1:

\documentclass[12pt, tikz, margin=3mm]{standalone}
\usetikzlibrary{arrows.meta, automata, positioning, quotes}

\begin{document}
    \begin{tikzpicture}[
node distance = 22mm and 24mm,
every state/.append style = {inner sep=0pt, fill=gray!10,
                             minimum size=7mm},
every edge/.style = {draw, -Triangle, bend angle=15},
                auto=right,
                        ]
\node (s1) [state,fill=gray!50]         {0};
\node (s2) [state, above right=of s1]   {2};
\node (s3) [state, right=of s2]         {$\infty$};
\node (s4) [state, below right=of s3]   {$\infty$};
\node (s5) [state, below  left=of s4]   {$\infty$};
\node (s6) [state, left=of s5]          {8};
%
\draw[gray!30, line width=5pt]
        (s1) to                     (s2)
        (s1) to [bend right=15]     (s6);
%
\draw   (s1) edge ["2"]             (s2)
        (s1) edge [bend right,"8"]  (s6)
        (s2) edge ["6"]             (s3)
        (s2) edge ["3"]             (s5)
        (s2) edge ["5"]             (s6)
        (s3) edge [out=135, in=90,looseness=1.5, "1"]  (s1)
        (s3) edge ["2"]             (s4)
        (s3) edge [bend right,"5"]  (s5)
        (s5) edge [bend right,"4"]  (s3)
        (s5) edge ["7"]             (s4)
        (s5) edge ["1"]             (s6)
        (s6) edge [bend right,"8"]  (s1);
   \end{tikzpicture}
\end{document}

代码2:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Welcome to Overleaf --- just edit your LaTeX on the left,
% and we'll compile it for you on the right. If you open the
% 'Share' menu, you can invite other users to edit at the same
% time. See www.overleaf.com/learn for more info. Enjoy!
%
% Note: you can export the pdf to see the result at full
% resolution.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\documentclass{beamer}

\usepackage{tikz}

\usepackage{verbatim}
\usetikzlibrary{arrows,shapes}


\begin{document}
\begin{comment}
:Title: Prim's algorithm
:Tags: Beamer, Layers, Foreach, Graphs
:Use page: 6


A step by step example of the `Prim's algorithm`_ for finding the `minimum
spanning tree`_. Animated using Beamer 
overlays.

.. _Prim's algorithm: http://en.wikipedia.org/wiki/Prim%27s_algorithm
.. _Minimum spanning tree: http://en.wikipedia.org/wiki/Minimum_spanning_tree

| Source: Adapted from an example on Wikipedia_

.. _Wikipedia: http://en.wikipedia.org/wiki/Prim%27s_algorithm
\end{comment}

% Declare layers
\pgfdeclarelayer{background}
\pgfsetlayers{background,main}

\begin{frame}
\frametitle{Prim's algorithm}

%% Adjacency matrix of graph
%% \  a  b  c  d  e  f  g
%% a  x  7     5
%% b  7  x  8  9  7
%% c     8  x     5
%% d  5  9     x 15  6
%% e     7  5 15  x  8  9
%% f           6  8  x 11
%% g              9  11 x

\tikzstyle{vertex}=[circle,fill=black!25,minimum size=20pt,inner sep=0pt]
\tikzstyle{selected vertex} = [vertex, fill=red!24]
\tikzstyle{edge} = [draw,thick,-]
\tikzstyle{weight} = [font=\small]
\tikzstyle{selected edge} = [draw,line width=5pt,-,red!50]
\tikzstyle{ignored edge} = [draw,line width=5pt,-,black!20]

\begin{figure}
\begin{tikzpicture}[scale=1.8, auto,swap]
    % Draw a 7,11 network
    % First we draw the vertices
    \foreach \pos/\name in {{(0,2)/a}, {(2,1)/b}, {(4,1)/c},
                            {(0,0)/d}, {(3,0)/e}, {(2,-1)/f}, {(4,-1)/g}}
        \node[vertex] (\name) at \pos {$\name$};
    % Connect vertices with edges and draw weights
    \foreach \source/ \dest /\weight in {b/a/7, c/b/8,d/a/5,d/b/9,
                                         e/b/7, e/c/5,e/d/15,
                                         f/d/6,f/e/8,
                                         g/e/9,g/f/11}
        \path[edge] (\source) -- node[weight] {$\weight$} (\dest);
    % Start animating the vertex and edge selection. 
    \foreach \vertex / \fr in {d/1,a/2,f/3,b/4,e/5,c/6,g/7}
        \path<\fr-> node[selected vertex] at (\vertex) {$\vertex$};
    % For convenience we use a background layer to highlight edges
    % This way we don't have to worry about the highlighting covering
    % weight labels. 
    \begin{pgfonlayer}{background}
        \pause
        \foreach \source / \dest in {d/a,d/f,a/b,b/e,e/c,e/g}
            \path<+->[selected edge] (\source.center) -- (\dest.center);
        \foreach \source / \dest / \fr in {d/b/4,d/e/5,e/f/5,b/c/6,f/g/7}
            \path<\fr->[ignored edge] (\source.center) -- (\dest.center);
    \end{pgfonlayer}
\end{tikzpicture}
\end{figure}

\end{frame}

\end{document}

代码3:

\documentclass{article}
\usepackage[utf8]{inputenc}

\usepackage{tikz}
\usetikzlibrary{positioning}

\begin{document}

%------------------------------------------------------------------------------
%Introductory example
\begin{figure}[p]
\begin{tikzpicture}
\filldraw[black] (0,0) circle (2pt) node[anchor=west] {Intersection point};
\draw[gray, thick] (-1,2) -- (2,-4);
\draw[gray, thick] (-1,-1) -- (2,2);
\end{tikzpicture}
\end{figure}
%------------------------------------------------------------------------------


%------------------------------------------------------------------------------
%Points, lineas and curves
\begin{figure}[p]
\begin{tikzpicture}
\draw (-2,0) -- (2,0);
\filldraw [gray] (0,0) circle (2pt);
\draw (-2,-2) .. controls (0,0) .. (2,-2);
\draw (-2,2) .. controls (-1,0) and (1,0) .. (2,2);

\end{tikzpicture}
\end{figure}
%------------------------------------------------------------------------------


%------------------------------------------------------------------------------
%Circles and arcs
\begin{figure}[p]
\begin{tikzpicture}
\filldraw[color=red!60, fill=red!5, very thick](-1,0) circle (1.5);
\fill[blue!50] (2.5,0) ellipse (1.5 and 0.5);
\draw[ultra thick, ->] (6.5,0) arc (0:220:1);
\end{tikzpicture}
\end{figure}
%------------------------------------------------------------------------------



%------------------------------------------------------------------------------
%Polygons
\begin{figure}[p]
\begin{tikzpicture}
\draw[blue, very thick] (0,0) rectangle (3,2);
\draw[orange, ultra thick] (4,0) -- (6,0) -- (5.7,2) -- cycle;
\end{tikzpicture}
\end{figure}
%------------------------------------------------------------------------------


%------------------------------------------------------------------------------
%Diagram
\begin{figure}
\begin{tikzpicture}[
roundnode/.style={circle, draw=green!60, fill=green!5, very thick, minimum size=7mm},
squarednode/.style={rectangle, draw=red!60, fill=red!5, very thick, minimum size=5mm},
]
%Nodes
\node[squarednode]      (maintopic)                              {2};
\node[roundnode]        (uppercircle)       [above=of maintopic] {1};
\node[squarednode]      (rightsquare)       [right=of maintopic] {3};
\node[roundnode]        (lowercircle)       [below=of maintopic] {4};

%Lines
\draw[->] (uppercircle.south) -- (maintopic.north);
\draw[->] (maintopic.east) -- (rightsquare.west);
\draw[->] (rightsquare.south) .. controls +(down:7mm) and +(right:7mm) .. (lowercircle.east);

\end{tikzpicture}
\end{figure}

%------------------------------------------------------------------------------


%------------------------------------------------------------------------------
%List of available colors 

\begin{figure}[p]
\begin{tikzpicture}
\filldraw[black] (0,0) rectangle (2,2);
\filldraw[red] (3,0) rectangle (5,2);
\filldraw[green] (6,0) rectangle (8,2);
\filldraw[blue] (9,0) rectangle (11,2);
\filldraw[cyan] (1,-1) rectangle (3,-3);
\filldraw[magenta] (4,-1) rectangle (6,-3);
\filldraw[yellow] (7,-1) rectangle (9,-3);
\end{tikzpicture}
\end{figure}
%------------------------------------------------------------------------------


%------------------------------------------------------------------------------
%Different levels of thickness
\begin{figure}[p]
\begin{tikzpicture}
\draw[blue, ultra thin] (-1,2) -- (1,-2);
\draw[blue, very thin] (0,2) -- (2,-2);
\draw[blue, thin] (1,2) -- (3,-2);
\draw[blue, thick] (2,2) -- (4,-2);
\draw[blue, very thick] (3,2) -- (5,-2);
\draw[blue, ultra thick] (4,2) -- (6,-2);
\end{tikzpicture}
\end{figure}
%------------------------------------------------------------------------------

\end{document}

答案1

不幸的是,我的tkz-graph软件包目前已“过时”。它需要更新

\documentclass{standalone} 
\usepackage{tkz-graph}

\begin{document} 

\begin{tikzpicture}
    \GraphInit[vstyle=Dijkstra]
    \SetGraphUnit{4}
    \Vertices{square}{G,D,A,F}
    \WE(F){H}
    \EA(A){B}
    \EA(D){C}
    \NO(A){E}
    \Edge[label=$1$](H)(F)
    \Edge[label=$4$](G)(F)
    \Edge[label=$2$](H)(G)
    \Edge[label=$2$](G)(D)
    \Edge[label=$3$](D)(C)
    \Edge[label=$4$](F)(E)
    \Edge[label=$3$](A)(D)
    \Edge[label=$2$](A)(E)
    \Edge[label=$1$](A)(B)
    \Edge[label=$2$](A)(C)
    \Edge[label=$2$](C)(B)
    \Edge[label=$3$](E)(B)
    \SetUpEdge[lw=4pt,color=red]
    \Edges[style={opacity=.2}](H,F,E,B)
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案2

我无法告诉你绘制这种图表的最有效方法是什么,但下面可能是一种相当有效的方法。节点的位置由距离决定,请参阅这里。(绘图中有一个距离不一致。)更重要的是,您可以使用它overlay-beamer-styles来使某些元素仅在某些覆盖层上可见。

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{arrows.meta, automata, calc,bending,positioning, quotes,
overlay-beamer-styles}
\tikzset{gl/.style={green!60!black,draw,bend left=20,-{Stealth[bend]},visible on=<#1>},
gr/.style={green!60!black,draw,bend right=20,-{Stealth[bend]},visible on=<#1>},
    shortcut/.code={\def\pv##1{\pgfkeysvalueof{/tikz/#1/##1}}},
    third corner of triangle/.style={shortcut=triangle pars,
    triangle pars/.cd,#1,
    /tikz/insert path={
     let \p1=($(\pv{A})-(\pv{B})$),\n1={sqrt(pow(\x1/1cm,2)+pow(\y1/1cm,2))},
      \n2={atan2(\y1,\x1)} in
     (intersection cs:first line={(\pv{A})--($(\pv{A})+({\n2-cosinelaw(\n1,\pv{b},\pv{a})}:1)$)},
     second line={(\pv{B})--($(\pv{B})+({\n2+cosinelaw(\n1,\pv{a},\pv{b})}:1)$)})
    }},
  declare function={cosinelaw(\a,\b,\c)=acos((\a*\a+\b*\b-\c*\c)/(2*\a*\b));},
  triangle pars/.cd,
  A/.initial=A,B/.initial=B,a/.initial=2,b/.initial=2}
\begin{document}
\begin{frame}[t]
\frametitle{An animated diagram}
\begin{tikzpicture}[
node distance = 22mm and 24mm,
every state/.append style = {inner sep=0pt, fill=gray!10,
                             minimum size=7mm},
every edge/.style = {draw}, auto=right]

 \path[scale=0.3] 
  node[state,label={[visible on=<2->]below left:a},
    alt=<3-5>{fill=yellow}{},
    alt=<6->{fill=red}{}](1){1}
  ++ (-15:7)  node[state,label={[blue,visible on=<3->]below:7},
    alt=<7->{fill=red}{}](2){2} 
  edge["7"] (1)
  [third corner of triangle={A=2,B=1,a=9,b=10}]
  node[state,label={[blue,visible on=<4->]above:9},alt=<8->{fill=red}{}
  ] (3){3}
  edge["9"] (1)
  edge["10"] (2)
  [third corner of triangle={A=2,B=3,a=11,b=15}] 
  node[state,alt=<8->{fill=red}{}] (4){4}
  edge["15"] (2)
  edge["11"] (3)
  [third corner of triangle={A=3,B=1,a=14,b=7}] 
  node[state,label={[blue,visible on=<5->]above:14}] (6){6}
  edge["14"] (1)
  edge["7"] (3)
  [third corner of triangle={A=4,B=6,a=9,b=6}]
    node[state,label={[visible on=<-2>]above right:b}
    ] (5){5}
  edge["6"] (4)
  edge["9"] (6)
  (1) edge[gr=3-] (2)
  (2) edge[gr=4-] (3); 
\end{tikzpicture}               
\end{frame}
\end{document}

在此处输入图片描述

当然,这并不是试图完全重现您链接的动画,但它为您提供了实现这一目标的工具。请注意,您也可以使用standaloneframe附带的\documentclass[beamer]{standalone}

附录:根据距离构建图表的方法,例如这个帖子。它利用了三角形在给定边长的情况下是唯一的(取决于符号选择)。因此,给定两个点和另外两个边的长度,您就可以确定第三个点(取决于符号)。

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{automata, calc,quotes}
\begin{document}
\begin{tikzpicture}[
every state/.append style = {inner sep=0pt, fill=gray!10,
                             minimum size=7mm},
every edge/.style = {draw}, auto=right,
    shortcut/.code={\def\pv##1{\pgfkeysvalueof{/tikz/#1/##1}}},
    third corner of triangle/.style={shortcut=triangle pars,
    triangle pars/.cd,#1,
    /tikz/insert path={
     let \p1=($(\pv{A})-(\pv{B})$),\n1={sqrt(pow(\x1/1cm,2)+pow(\y1/1cm,2))},
      \n2={atan2(\y1,\x1)} in
     (intersection cs:first line={(\pv{A})--($(\pv{A})+({\n2-cosinelaw(\n1,\pv{b},\pv{a})}:1)$)},
     second line={(\pv{B})--($(\pv{B})+({\n2+cosinelaw(\n1,\pv{a},\pv{b})}:1)$)})
    }},
  declare function={cosinelaw(\a,\b,\c)=acos((\a*\a+\b*\b-\c*\c)/(2*\a*\b));},
  triangle pars/.cd,
  A/.initial=A,B/.initial=B,a/.initial=2,b/.initial=2]

 \path[scale=0.3] 
  node[state,label={below left:a}](1){1}
  ++ (-15:7)  node[state,label={[blue]below:7}](2){2} 
  edge["7"] (1)
  [third corner of triangle={A=2,B=1,a=9,b=10}]
  node[state,label={[blue]above:9}] (3){3}
  edge["9"] (1)
  edge["10"] (2)
  [third corner of triangle={A=2,B=3,a=11,b=15}] 
  node[state] (4){4}
  edge["15"] (2)
  edge["11"] (3)
  [third corner of triangle={A=3,B=1,a=14,b=7}] 
  node[state,label={[blue]above:14}] (6){6}
  edge["14"] (1)
  edge["7"] (3)
  [third corner of triangle={A=4,B=6,a=9,b=6}]
    node[state,label={above right:b}] (5){5}
  edge["6"] (4)
  edge["9"] (6); 
\end{tikzpicture}               
\end{document}

在此处输入图片描述

答案3

我喜欢问题描述中的解决方案#2,只需删除动画部分并将其粘贴在此处以供参考:

\documentclass[tikz]{standalone}
\begin{document}
    \begin{tikzpicture}
    \tikzset{
        vertex/.style={circle,opacity=.8,fill=black!25,minimum size=20pt,inner sep=0pt},
        edge/.style={draw,thick,-,auto},
        weight/.style={font=\small},
    }
    % \node[anchor=south west,inner sep=0,opacity=1] (M) at (0,0){\includegraphics{a.png}};
    \begin{scope}
    \tikzset{
        % x={(M.south east)},y={(M.north west)},
        x=283,y=222,
    }
    % \foreach \x in {0,1,...,9} { \node [anchor=north] at (\x/10,0) {0.\x}; }
    % \foreach \y in {0,1,...,9} { \node [anchor=east] at (0,\y/10) {0.\y}; }
    % 
    \foreach \pos/\name/\label in {
        (0.13,0.21)/1/0,
        (0.46,0.09)/2/$\infty$,
        (0.43,0.59)/3/$\infty$,
        (0.93,0.63)/4/$\infty$,
        (0.58,0.88)/5/$\infty$,
        (0.18,0.8)/6/$\infty$} {
        \node[vertex,label=\label] (\name) at \pos {$\name$};
    }
    % 
    \foreach \source/ \dest /\weight in {
        1/2/7, 
        1/3/9,
        1/6/14,
        2/4/15,
        2/3/10, 
        3/4/11,
        3/6/2,
        4/5/6,
        5/6/9} {
        \path[edge] (\source) -- node[weight] {$\weight$} (\dest);
    }
    \end{scope}
    \end{tikzpicture}
\end{document}

您可以使用参考图片来获取准确的节点位置,删除注释行并将参考图片放在那里,然后您就可以获得准确的坐标来填充节点位置循环。然后在完成所有操作后,只需将其注释掉并使用图片宽度/高度作为 x / y 来获取最终图片。

在此处输入图片描述

相关内容