如何绘制块图(多个完整子图连接在一起)

如何绘制块图(多个完整子图连接在一起)

我想画一个块图。块图(或团树)是一种图,其中每个双连通分量(块)都是一个团。团是图中顶点(节点)的子集,其中团中的每两个不同顶点(节点)都是相邻的。基本上,块图是许多完整的子图($K_n$)连接在一起。

我附上了我想要绘制的块图的草图。它由 $K_7$、$K_5$、$K_4$、$K_1$ 和两个 $K_3$ 组成。块图

我在这个论坛上找到了一些代码,可以得到 $K_7$、$K_5$ 和 $K_3$。但是,它并没有完全解决问题。我只希望团共享一个顶点,并且希望它们在不同的位置旋转(如图所示)。

此外,LateX 代码中的顶点(节点)太大,即使我改变半径的大小,似乎也无法使它们变小。

这是我的 MWE:

\documentclass{article}
\usepackage{ifthen}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric, positioning, calc}
\tikzset{%
    mynode/.style={%
        circle, radius=2pt, draw=darkgray, fill=white
    }
}

\begin{document}
    \begin{tikzpicture}
        \node[minimum size=4cm, regular polygon, regular polygon sides=7, rotate=180] (epta) {};
        \foreach \x in {1,2,...,7}{%
            \node[mynode] at (epta.corner \x) (e\x) {};
        }
        \foreach \x in {1,2,...,7}{%
            \foreach \y in {1,2,...,7}{%
                \ifthenelse{\x>\y}{}{\draw[darkgray] (e\x) -- (e\y);}       
        }}
        \node[below= 2pt of e1] {};
        \node[below= 2pt of e2] {};
        \node[above right = 2pt and -1pt of e3] {};
        \node[above right = 0pt and -1pt of e4] {};
        \node[above left = 0pt and -1pt of e5] {};
        \node[below left = 0pt and -1pt of e6] {};
        \node[below left = 0pt and -1pt of e7] {};
        \node(p1) at (e2) {};
        \node(p2) at (e3) {};
        
        \foreach \nextp/\prevp/\i in {p3/p2/1,p4/p3/2,p5/p4/3}{%
            \node[mynode] (\nextp) at ($(\prevp)+(77-\i*72:50pt)$) {};
        }    
        \foreach \x in {1,2,...,5}{%
            \foreach \y in {1,2,...,5}{%
                \ifthenelse{\x>\y}{}{\draw[darkgray] (p\x) -- (p\y);}       
        }}

        \node[mynode, below right = 40pt and 1pt of e2, label={[label distance=2pt]-90:}] (s1) {};
        \draw[darkgray] (e1) -- (p5) -- (s1) -- (e1);

    \end{tikzpicture}
\end{document} 

目前结果:

结果

任何帮助将不胜感激!

答案1

考虑到该库的强大功能(参见 Qrrbrbirlbel 的解决方案),这可能有点重新发明轮子graphs,但这是一个自己动手的可能性。

该命令\complete[<prefix>]{<num nodes>}{<start coordinate>}{<radius of circle>}{<direction toward center>}将执行您想要的操作。

在此处输入图片描述

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{calc}

\tikzset{
    vertex/.style={draw, thick, circle, minimum size=3mm, inner sep=0pt}
}

\newcommand{\complete}[5][]{
    \foreach \k in {1,...,#2} \node[vertex](#1\k) at ($([shift=(#5:#4)]#3)+({360/#2*(\k-1)+180+#5}:#4)$){};
    \foreach \k in {1,...,#2} \foreach \j in {1,...,\k} \draw(#1\k)--(#1\j);
} % #1=node label prefix, #2=n vertices, #3=start coordinate, #4=radius, optional #5=angle toward center
\begin{document}

\begin{tikzpicture}
\complete[N]{7}{0,0}{2cm}{0}
\complete[M]{5}{N5}{1.5cm}{30}
\complete[P]{3}{M3}{1cm}{0}
\complete[Q]{3}{M2}{1cm}{-90}
\complete[R]{2}{Q3}{.5cm}{0}
\complete[S]{4}{R2}{1cm}{0}
\end{tikzpicture}

\end{document}

答案2

graphs/库graphs.standard已经带来了subgraph K_n它会自动将所有节点相互连接。

随着counterclockwise钥匙我们将激活circular placement将节点放置在圆上的策略。它使用radius钥匙phase钥匙n节点放置在圆圈上。

然后该习俗joined subgraph K_n可以用来“加入”另一个n与节点形成join in一个圆圈的节点n+1 个节点。

密钥position决定了该节点在这个新子图中的位置join in。位置0代表阶段 0,位置 1 代表位置 之后的下一个节点0。它基本上是一个phase转换为节点位置的值。我希望这可以减少用户所需的计算,但它也有点晦涩难懂……

请注意,的值n仅指定新的新子图中的节点数而不是包括该节点在内的总数join in


graphs库仅提供了用于放置和连接节点的新的、更短的语法。它不提供任何无法通过\nodes 和edges 实现的功能。

代码

\documentclass[tikz]{standalone}
\usetikzlibrary{graphs.standard}
\newcommand*\tg[1]{\pgfkeysvalueof{/tikz/graphs/#1}}
\tikzgraphsset{
  show my name/.style={
    label={[node font=\tiny, inner sep=+0pt, magenta]\tikzgraphnodefullname}},
  join in/.initial=, position/.initial=0,
  declare={joined subgraph K_n}{
    [
      /utils/exec=%
        \pgfmathtruncatemacro\tgN{\tikzgraphVnum+1}%
        \pgfmathsetmacro\tgPhase{(\tg{position})*360/\tgN},
      /tikz/shift/.expanded={(\tg{join in})},
      /tikz/shift/.expanded={(\tgPhase:{-(\tg{radius})})},
    ] (\tg{join in}) --
    subgraph K_n[counterclockwise=\tgN, phase=\tgPhase+360/\tgN]}}
\begin{document}
\tikz[
  vertex/.style={
    shape=circle, draw,
    inner sep=+0pt, minimum size=+3pt}, % radius is not a shape key
  thick,
]
\graph[
  empty nodes,  % no text in nodes
  nodes=vertex, % all nodes be of style vertex
  radius=1cm,   % base radius (also default)
  nodes=show my name, % debug the names
] {
  % for the heptagraph we're using the built-in subgraph:
  %  n = 7            → seven nodes
  %  counterclockwise → arranged in a circle
  %  phase = -90      → the first one is at -90
  % this uses the radius = 1cm value to place the nodes on a circle
  % they are named “seven 1”, “seven 2”, …
         subgraph K_n[name=seven,  n=7, counterclockwise, phase=-90],
  % the next one is already a custom joined subgraph K_n
  % which always create a counterclockwise addition
  % where one of the nodes in that circle is already occupied by
  % “join in” at the “position” where position
  %  is counted from angle 0° → position = 0
  % the “n” value here is the number of additions without the “join in” node
  joined subgraph K_n[name=five,   n=4, join in=seven 3,  position=3],
  {[radius=.75cm]
    joined subgraph K_n[name=threeA, n=2, join in=five 2,   position=1.5 ],
    joined subgraph K_n[name=threeB, n=2, join in=five 1,   position=0.75],
    joined subgraph K_n[name=two,    n=1, join in=threeB 2, position=1   , radius=.5cm],
    joined subgraph K_n[name=four,   n=3, join in=two 1,    position=2   ]
  }
};
\end{document}

输出

在此处输入图片描述

相关内容