
Antwort1
mit nicematrix
ist es super einfach
\documentclass{article}
\usepackage{nicematrix}
\begin{document}
\[
\mathbf{A}_H =
\begin{bNiceMatrix}[first-row,first-col]
& v_6 & v_3 & v_4 & v_5 & v_1 & v_2 \\
v_6 & 0 & 1 & 0 & 1 & 0 & 0 \\
v_3 & 1 & 0 & 1 & 0 & 0 & 1 \\
v_4 & 0 & 1 & 0 & 1 & 0 & 0 \\
v_5 & 1 & 0 & 1 & 0 & 1 & 0 \\
v_1 & 0 & 0 & 0 & 1 & 0 & 1 \\
v_2 & 0 & 1 & 0 & 0 & 1 & 0 \\
\end{bNiceMatrix}
\]
\end{document}
Antwort2
Dies ist ein interessantes Problem. Hier definiere ich eine Datenstruktur für Graphen, die das Drucken der Adjazenzmatrix ermöglicht, aber wir können uns auch andere Verwendungsmöglichkeiten vorstellen.
Die Idee besteht darin, die Indizes für die Eckpunkte in einer Sequenz und die Liste der Kanten in einer anderen Sequenz zu speichern.
Die Scheitelpunktliste wird (zweimal) zugeordnet, um zu prüfen, ob eine bestimmte Kante in der Kantenliste enthalten ist. In diesem Fall 1
wird sie zum Hauptteil der Matrix hinzugefügt, andernfalls 0
.
Die Verwendung nicematrix
ermöglicht das Ausfüllen auch der äußeren Zeilen und Spalten.
\documentclass{article}
\usepackage{nicematrix}
\ExplSyntaxOn
\NewDocumentCommand{\definegraph}{mmm}
{% #1 = graph name, #2 = vertex list, #3 = edge list
\ryl_graph_define:nnn { #1 } { #2 } { #3 }
}
\NewDocumentCommand{\adjacencymatrix}{m}
{% #1 = graph name
\ryl_graph_adjacency:n { #1 }
}
\cs_new_protected:Nn \ryl_graph_define:nnn
{
\seq_clear_new:c { l__graph_vertex_#1_seq }
\seq_set_from_clist:cn { l__graph_vertex_#1_seq } { #2 }
\seq_clear_new:c { l__graph_edge_#1_seq }
\seq_set_from_clist:cn { l__graph_edge_#1_seq } { #3 }
}
\tl_new:N \l__ryl_graph_adjacency_tl
\cs_new_protected:Nn \ryl_graph_adjacency:n
{
\tl_clear:N \l__ryl_graph_adjacency_tl
\seq_map_inline:cn { l__graph_vertex_#1_seq }
{
\tl_put_right:Nn \l__ryl_graph_adjacency_tl { & v\sb{##1} }
}
\tl_put_right:Nn \l__ryl_graph_adjacency_tl { \\ }
\seq_map_inline:cn { l__graph_vertex_#1_seq }
{
\tl_put_right:Nn \l__ryl_graph_adjacency_tl { v\sb{##1} }
\seq_map_inline:cn { l__graph_vertex_#1_seq }
{
\seq_if_in:cnTF { l__graph_edge_#1_seq } { ##1-####1 }
{% the edge is in
\tl_put_right:Nn \l__ryl_graph_adjacency_tl { & 1 }
}
{
\seq_if_in:cnTF { l__graph_edge_#1_seq } { ####1-##1 }
{% the edge is in
\tl_put_right:Nn \l__ryl_graph_adjacency_tl { & 1 }
}
{
\tl_put_right:Nn \l__ryl_graph_adjacency_tl { & 0 }
}
}
}
\tl_put_right:Nn \l__ryl_graph_adjacency_tl { \\ }
}
\begin{bNiceMatrix}[first-row,first-col]
\tl_use:N \l__ryl_graph_adjacency_tl
\end{bNiceMatrix}
}
\ExplSyntaxOff
\definegraph{A}{1,2,3}{1-2,1-3,2-3}
\definegraph{B}{6,3,4,5,1,2}{6-3,6-5,3-6,3-4,3-2,4-3,4-5,5-1,1-2}
\begin{document}
\[
\adjacencymatrix{A}
\]
\[
\mathbf{A}_{H}=\adjacencymatrix{B}
\]
\end{document}
Im zweiten Beispiel können Sie sehen, dass das Auflisten doppelter Kanten irrelevant ist.