是否有任何 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}
被替换为1
或0
:
代码:
\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 可以改进,但无论如何这都可以解决问题 :)array
pmatrix
\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}
您可以定义和存储任意数量的图形规范。也可以使用逗号来分隔边规范,但我认为最好保持区别(更多结构 = 更多信息)。