来自图形描述的矩阵

来自图形描述的矩阵

是否有任何 LaTeX 包可以根据“图形”描述(节点关系)绘制/绘制/生成矩阵。任何类型的描述/语言都可能有用。诀窍是从“关系”描述中自动生成矩阵。

例如,从以下“数学”关系:

(1, 1)
(1, 2)
(1, 5)
(2, 1)
(2, 3)
(2, 5)
(3, 2)
(3, 4)
(4, 3)
(4, 5)
(4, 6)
(5, 1)
(5, 2)
(5, 4)
(6, 4)

其代表下一个图表:

示例图

得到此关系的以下矩阵表示:

矩阵表示

LaTeX 是否有可用的软件包来完成这种类型的“翻译”?(从数学关系到其对应图的矩阵表示)。

答案1

这是实现此目的的一种方法(有很大的改进空间)。给定一个节点关系列表:

\newcommand{\NodeRelations}{%
    (1,1),
    (1,2),
    (1,5),
    (2,1),
    (2,3),
    (2,5),
    (3,2),
    (3,4),
    (4,3),
    (4,5),
    (4,6),
    (5,1),
    (5,2),
    (5,4),
    (6,4)
}%

您使用MyMatrix环境并传入虚拟数据:

\begin{MyMatrix}{\NodeRelations}
    - & - & - & - & - & - \\
    - & - & - & - & - & - \\
    - & - & - & - & - & - \\
    - & - & - & - & - & - \\
    - & - & - & - & - & - \\
    - & - & - & - & - & - \\
\end{MyMatrix}

被替换为10

在此处输入图片描述

代码:

\documentclass{article}
\usepackage{pgffor}
\usepackage{xstring}
\usepackage{collcell}
\usepackage{etoolbox}

\newcounter{RowCount}
\newcounter{ColCount}

\newcommand*{\NextColumn}[1]{%
    \addtocounter{ColCount}{1}%
    \IfIsInNodeRelations{\arabic{ColCount}}{\arabic{RowCount}}{1}{0}%
}
\newcommand*{\FirstColumn}[1]{%
    \setcounter{ColCount}{0}%
    \addtocounter{RowCount}{1}%
    \NextColumn{#1}%
}


\newtoggle{IsInNodeRelations}
\newcommand*{\IfIsInNodeRelations}[4]{%
    \global\togglefalse{IsInNodeRelations}%
    \foreach \Node in \NodeRelations {%
        \StrBetween{\Node}{(}{,}[\x]
        \StrBetween{\Node}{,}{)}[\y]
        \IfEq{\x}{#1}{%
            \IfEq{\y}{#2}{%
                \global\toggletrue{IsInNodeRelations}%
                \breakforeach%
            }{}%
        }{}%
    }%
    \iftoggle{IsInNodeRelations}{#3}{#4}
}

\newcommand{\NodeRelations}{%
    (1,1),
    (1,2),
    (1,5),
    (2,1),
    (2,3),
    (2,5),
    (3,2),
    (3,4),
    (4,3),
    (4,5),
    (4,6),
    (5,1),
    (5,2),
    (5,4),
    (6,4)
}%

\newcommand*{\ExtractedX}{}%
\newcommand*{\ExtractedY}{}%
\def\ExtractXY(#1,#2){%
    \xdef\ExtractedX{#1}%
    \xdef\ExtractedY{#2}%
}%

\newenvironment{MyMatrix}[1]{%
    % #1 = List of node relations
    \newcolumntype{F}{>{\collectcell\FirstColumn}c<{\endcollectcell}}%
    \newcolumntype{C}{>{\collectcell\NextColumn}c<{\endcollectcell}}%
    \setcounter{RowCount}{0}
    \setcounter{ColCount}{0}
    $\left[\begin{array}{F C C C C C}%
}{%
    \end{array}\right]$%
}%

\begin{document}


\begin{MyMatrix}{\NodeRelations}
    - & - & - & - & - & - \\
    - & - & - & - & - & - \\
    - & - & - & - & - & - \\
    - & - & - & - & - & - \\
    - & - & - & - & - & - \\
    - & - & - & - & - & - \\
\end{MyMatrix}
\end{document}

答案2

看起来 Peter 已经为你做好了准备,所以这里有一个 LuaLaTeX 选项仅供比较。你可以直接传递这些对,也可以将它们存储在宏中并传递。我留下了使用你喜欢的任何数组环境的选项(即、bmatrix等)。我确信我的 Lua 可以改进,但无论如何这都可以解决问题 :)arraypmatrix

在此处输入图片描述

\documentclass{article}
\usepackage{luacode}
\usepackage{mathtools}

\begin{luacode*}
function adjmat(lst)
    local edges = {}
    local n = 0
    for hit in string.gmatch(lst,"%b()") do
        for r,c in string.gmatch(hit, "%((.+),(.+)%)") do
            edges[tonumber(r)] = edges[tonumber(r)] or {}
            edges[tonumber(r)][tonumber(c)] = 1
            n = math.max(n,r,c)
        end
    end
    for i = 1,n do
        local mat = ""
        edges[i] = edges[i] or {}
        for j = 1,n do
            edges[i][j] = edges[i][j] or 0
            mat = mat..edges[i][j].."&" 
        end
        tex.sprint(string.sub(mat,1,-2))
        tex.print("\\\\")
    end
end
\end{luacode*}

\def\adjmat#1{\directlua{adjmat("\luatexluaescapestring{#1}")}}

\begin{document}

\def\mymattwo{(1, 1),(1, 2),(1, 5),(2, 1),(2, 3),(2, 5),(3, 2),(3, 4),(4, 3),(4, 5),(4, 6),(5, 1),(5, 2),(5, 4),(6, 4)}

\[
    \begin{bmatrix}
        \adjmat{(1,1),(3,2),(4,5),(1,1),(2,1)}
    \end{bmatrix}
\]

\[
    \begin{bmatrix}
        \adjmat\mymattwo
    \end{bmatrix}
\]

\end{document}

答案3

这是一个expl3实现:

\documentclass{article}
\usepackage{xparse,amsmath}
\ExplSyntaxOn
\NewDocumentCommand{\definegraph}{ o m }
 {
  \IfNoValueTF{#1}
   {
    \graphs_define:nn { default } { #2 }
   }
   {
    \msg_term:n { I'm~(re)defining~graph~#1 }
    \graphs_define:nn { #1 } { #2 }
   }
 }

\tl_new:N \l__graphs_temp_tl
\seq_new:N \l__graphs_temp_seq
\int_new:N \l__graphs_count_int
\prop_new:N \g_graphs_list_prop

\cs_new_protected:Npn \graphs_define:nn #1 #2
 {
  % remove spaces
  \tl_set:Nn \l__graphs_temp_tl { #2 }
  \tl_remove_all:Nn \l__graphs_temp_tl { ~ }
  % store the list of edges
  \prop_gput:NnV \g_graphs_list_prop { #1 edges } \l__graphs_temp_tl
  % get the number of nodes
  \tl_remove_all:Nn \l__graphs_temp_tl { ( }
  \tl_remove_all:Nn \l__graphs_temp_tl { ) }
  \tl_replace_all:Nnn \l__graphs_temp_tl { , } { ; }
  \seq_set_split:NnV \l__graphs_temp_seq { ; } \l__graphs_temp_tl
  \seq_remove_duplicates:N \l__graphs_temp_seq
  % store the number of nodes
  \prop_gput:Nnx \g_graphs_list_prop { #1 length } { \int_to_arabic:n { \seq_count:N \l__graphs_temp_seq } }
 }

\NewDocumentCommand{\adjacencymatrix} { O{default} }
 {
  \graphs_build_adjmatr:n { #1 }
 }
\cs_new:Npn \graphs_build_adjmatr:n #1
 {
  % retrieve the list of nodes
  \prop_get:NnN \g_graphs_list_prop { #1 edges } \l__graphs_temp_tl
  % split the list into a sequence
  \seq_set_split:NnV \l__graphs_temp_seq { ; } \l__graphs_temp_tl
  % retrieve the number of nodes
  \int_set:Nn \l__graphs_count_int { \prop_get:Nn \g_graphs_list_prop { #1 length } }
  % start building the matrix
  \tl_clear:N \l__graphs_temp_tl
  % the outer loop indexes the rows, the inner loop the columns
  \int_step_inline:nnnn { 1 } { 1 } { \l__graphs_count_int }
   {
    \int_step_inline:nnnn { 1 } { 1 } { \l__graphs_count_int }
     { \__graphs_put_coeff:nn { ##1 } { ####1 } }
    \tl_put_right:Nn \l__graphs_temp_tl { \\ }
   }
  \begin{bmatrix}\l__graphs_temp_tl\end{bmatrix}
 }
% An auxiliary function for the lower level code:
% add 1 if the edge is listed, add 0 otherwise;
% then place the & if not in the last column.
\cs_new:Npn \__graphs_put_coeff:nn #1 #2
 {
  \seq_if_in:NnTF \l__graphs_temp_seq { (#1,#2) }
   { \tl_put_right:Nn \l__graphs_temp_tl { 1 } }
   { \tl_put_right:Nn \l__graphs_temp_tl { 0 } }
  \int_compare:nT { #2 < \l__graphs_count_int }
   { \tl_put_right:Nn \l__graphs_temp_tl { & } }
 }

\ExplSyntaxOff

\begin{document}

\definegraph{(1,2);(1,3);(2,3);(4,5)}

$\adjacencymatrix$

\definegraph{(1,2);( 1,3) ;(2 , 3); ( 4 , 5)} % spaces are insignificant

$\adjacencymatrix$

\definegraph[IK]{
    (1,1);
    (1,2);
    (1,5);
    (2,1);
    (2,3);
    (2,5);
    (3,2);
    (3,4);
    (4,3);
    (4,5);
    (4,6);
    (5,1);
    (5,2);
    (5,4);
    (6,4)
}

$\adjacencymatrix[IK]$
\end{document}

您可以定义和存储任意数量的图形规范。也可以使用逗号来分隔边规范,但我认为最好保持区别(更多结构 = 更多信息)。

在此处输入图片描述

相关内容