finish pythonifying data, minor revisions to permutations.2

This commit is contained in:
queue-miscreant 2025-07-06 02:53:04 -05:00
parent 2c1775e8f2
commit f5d6614462
8 changed files with 417 additions and 248 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 KiB

View File

@ -54,9 +54,9 @@ class SymmetricSpectrum:
shown_roots = len(polynomial_roots) > 0 or len(integer_roots) > 0 shown_roots = len(polynomial_roots) > 0 or len(integer_roots) > 0
not_shown_string = ( not_shown_string = (
( (
f"Not shown: {self.not_shown_count} other roots" f"*Not shown: {self.not_shown_count} other roots*"
if shown_roots if shown_roots
else f"Not shown: all {self.not_shown_count} roots" else f"*Not shown: all {self.not_shown_count} roots*"
) )
if self.not_shown_count > 0 if self.not_shown_count > 0
else "" else ""
@ -69,13 +69,13 @@ class SymmetricSpectrum:
) )
return ( return (
( (
"$$\\begin{gather*}" "$$\\begin{gather*}"
+ " \\\\ ".join( + " \\\\ ".join(
display_integral_root(*rm, pad_to=longest_integer) display_integral_root(*rm, pad_to=longest_integer)
for rm in integer_roots for rm in integer_roots
)
+ "\\end{gather*}$$"
) )
+ "\\end{gather*}$$"
)
if shown_roots if shown_roots
else "" else ""
) + not_shown_string ) + not_shown_string
@ -97,16 +97,17 @@ class SymmetricSpectrum:
) )
) )
return (( return (
"$$\\begin{gather*}" (
+ integral_roots_lines "$$\\begin{gather*}"
+ " \\\\ " + integral_roots_lines
+ " \\\\ ".join( + " \\\\ "
sympy.latex(root**multiplicity) + " \\\\ ".join(
for root, multiplicity in polynomial_roots sympy.latex(root**multiplicity)
for root, multiplicity in polynomial_roots
)
+ "\\end{gather*}$$"
) )
+ "\\end{gather*}$$"
)
if shown_roots if shown_roots
else "" else ""
) + not_shown_string ) + not_shown_string
@ -127,9 +128,10 @@ def count_roots_spectrum(spectrum: SymmetricSpectrum) -> int:
+ spectrum.not_shown_count + spectrum.not_shown_count
) )
@dataclass @dataclass
class GraphData: class GraphData:
vertex_count: int
edge_count: int
distance_classes: list[int]
spectrum: SymmetricSpectrum spectrum: SymmetricSpectrum
vertex_count: int | None = None
edge_count: int | None = None
distance_classes: list[int] | None = None

View File

@ -1,50 +1,80 @@
from .base import SymmetricSpectrum from .base import GraphData, SymmetricSpectrum
# TODO: other non-spectral data # TODO: other non-spectral data
complete_spectra = { data = {
3: SymmetricSpectrum([(0, 4), (3, 1)]), 3: GraphData(
4: SymmetricSpectrum([(0, 4), (2, 9), (6, 1)]), vertex_count=6,
5: SymmetricSpectrum( edge_count=9,
[ distance_classes=[1, 3, 2],
(0, 36), spectrum=SymmetricSpectrum([(0, 4), (3, 1)]),
(2, 25),
(5, 16),
(10, 1),
]
), ),
6: SymmetricSpectrum( 4: GraphData(
[ vertex_count=24,
(0, 256), edge_count=72,
(3, 125), distance_classes=[1, 6, 11, 6],
(5, 81), spectrum=SymmetricSpectrum([(0, 4), (2, 9), (6, 1)]),
(9, 25),
(15, 1),
]
), ),
7: SymmetricSpectrum( 5: GraphData(
[ vertex_count=120,
(0, 400), edge_count=600,
(1, 441), distance_classes=[1, 10, 35, 50, 24],
(3, 1225), spectrum=SymmetricSpectrum(
(6, 196), [
(7, 225), (0, 36),
(9, 196), (2, 25),
(14, 36), (5, 16),
(21, 1), (10, 1),
] ]
),
),
6: GraphData(
vertex_count=720,
edge_count=5400,
distance_classes=[1, 15, 85, 225, 274, 120],
spectrum=SymmetricSpectrum(
[
(0, 256),
(3, 125),
(5, 81),
(9, 25),
(15, 1),
]
),
),
7: GraphData(
vertex_count=5040,
edge_count=52920,
distance_classes=[1, 21, 175, 735, 1624, 1764, 720],
spectrum=SymmetricSpectrum(
[
(0, 400),
(1, 441),
(3, 1225),
(6, 196),
(7, 225),
(9, 196),
(14, 36),
(21, 1),
]
),
), ),
# TODO: missing a root (and its negative) of multiplicity 400 # TODO: missing a root (and its negative) of multiplicity 400
8: SymmetricSpectrum( 8: GraphData(
[ vertex_count=40320,
(0, 9864), spectrum=SymmetricSpectrum(
(2, 3136), [
(4, 6125), (0, 9864),
(7, 4096), (2, 3136),
(8, 196), (4, 6125),
(10, 784), (7, 4096),
(12, 441), (8, 196),
(20, 49), (10, 784),
(28, 1), (12, 441),
] (20, 49),
(28, 1),
]
)
), ),
} }
# TODO (maybe): verify these quantities with outputs from Haskell

View File

@ -1,50 +1,101 @@
from .base import SymmetricSpectrum, x from .base import SymmetricSpectrum, GraphData, x
path_spectra = { data = {
3: SymmetricSpectrum( 3: GraphData(
[(1, 2), (2, 1)] vertex_count=6,
edge_count=6,
distance_classes=[1, 2, 2, 1],
spectrum=SymmetricSpectrum([(1, 2), (2, 1)]),
), ),
4: SymmetricSpectrum( 4: GraphData(
[ vertex_count=24,
(1, 3), edge_count=36,
(3, 1), distance_classes=[1, 3, 5, 6, 5, 3, 1],
(x**2 - 3, 2), spectrum=SymmetricSpectrum(
(x**2 - 2 * x - 1, 3), [
(x**2 + 2 * x - 1, 3), (1, 3),
] (3, 1),
(x**2 - 3, 2),
(x**2 - 2 * x - 1, 3),
(x**2 + 2 * x - 1, 3),
]
),
), ),
5: SymmetricSpectrum( 5: GraphData(
[ vertex_count=120,
(0, 12), edge_count=240,
(1, 6), distance_classes=[1, 4, 9, 15, 20, 22, 20, 15, 9, 4, 1],
(4, 1), spectrum=SymmetricSpectrum(
(x**2 - 5, 6), [
(x**2 + 5 * x + 5, 4), (0, 12),
(x**2 + 3 * x + 1, 4), (1, 6),
(x**2 + 2 * x - 1, 5), (4, 1),
(x**3 + 2 * x**2 - 5 * x - 4, 5), (x**2 - 5, 6),
] (x**2 + 5 * x + 5, 4),
(x**2 + 3 * x + 1, 4),
(x**2 + 2 * x - 1, 5),
(x**3 + 2 * x**2 - 5 * x - 4, 5),
]
),
), ),
6: SymmetricSpectrum( 6: GraphData(
[ vertex_count=720,
(0, 20), edge_count=1800,
(1, 25), distance_classes=[1, 5, 14, 29, 49, 71, 90, 101, 101, 90, 71, 49, 29, 14, 5, 1],
(2, 15), spectrum=SymmetricSpectrum(
(3, 5), [
(4, 5), (0, 20),
(5, 1), (1, 25),
(x**2 - 3, 20), (2, 15),
(3, 5),
(4, 5),
(5, 1),
(x**2 - 3, 20),
],
not_shown_count=558,
),
),
7: GraphData(
vertex_count=5040,
edge_count=15120,
distance_classes=[
1,
6,
20,
49,
98,
169,
259,
359,
455,
531,
573,
573,
531,
455,
359,
259,
169,
98,
49,
20,
6,
1,
], ],
not_shown_count=558, spectrum=SymmetricSpectrum(
[
(0, 35),
(1, 20),
(2, 45),
(6, 1),
],
not_shown_count=4873,
),
), ),
7: SymmetricSpectrum( 8: GraphData(
[ vertex_count=40320,
(0, 35), spectrum=SymmetricSpectrum([], not_shown_count=40320)
(1, 20),
(2, 45),
(6, 1),
],
not_shown_count=4873,
), ),
8: SymmetricSpectrum([], not_shown_count=40320),
} }
# TODO (maybe): verify these quantities with outputs from Haskell

View File

@ -1,55 +1,85 @@
from .base import SymmetricSpectrum from .base import SymmetricSpectrum, GraphData
star_spectra = { data = {
3: SymmetricSpectrum([(1, 2), (2, 1)]), 3: GraphData(
4: SymmetricSpectrum( vertex_count=6,
[ edge_count=6,
(0, 4), distance_classes=[1, 2, 2, 1],
(1, 3), spectrum=SymmetricSpectrum([(1, 2), (2, 1)]),
(2, 6),
(3, 1),
]
), ),
5: SymmetricSpectrum( 4: GraphData(
[ vertex_count=24,
(0, 30), edge_count=36,
(1, 4), distance_classes=[1, 3, 6, 9, 5],
(2, 28), spectrum=SymmetricSpectrum(
(3, 12), [
(4, 1), (0, 4),
] (1, 3),
(2, 6),
(3, 1),
]
),
), ),
6: SymmetricSpectrum( 5: GraphData(
[ vertex_count=120,
(0, 168), edge_count=240,
(1, 30), distance_classes=[1, 4, 12, 30, 44, 26, 3],
(2, 120), spectrum=SymmetricSpectrum(
(3, 105), [
(4, 20), (0, 30),
(5, 1), (1, 4),
] (2, 28),
(3, 12),
(4, 1),
]
),
), ),
7: SymmetricSpectrum( 6: GraphData(
[ vertex_count=720,
(0, 840), edge_count=1800,
(1, 468), distance_classes=[1, 5, 20, 70, 170, 250, 169, 35],
(2, 495), spectrum=SymmetricSpectrum(
(3, 830), [
(4, 276), (0, 168),
(5, 30), (1, 30),
(6, 1), (2, 120),
] (3, 105),
(4, 20),
(5, 1),
]
),
), ),
8: SymmetricSpectrum( 7: GraphData(
[ vertex_count=5040,
(0, 3960), edge_count=15120,
(1, 5691), distance_classes=[1, 6, 30, 135, 460, 1110, 1689, 1254, 340, 15],
(2, 2198), spectrum=SymmetricSpectrum(
(3, 6321), [
(4, 3332), (0, 840),
(5, 595), (1, 468),
(6, 42), (2, 495),
(7, 1), (3, 830),
] (4, 276),
(5, 30),
(6, 1),
]
),
),
8: GraphData(
vertex_count=40320,
spectrum=SymmetricSpectrum(
[
(0, 3960),
(1, 5691),
(2, 2198),
(3, 6321),
(4, 3332),
(5, 595),
(6, 42),
(7, 1),
]
)
), ),
} }
# TODO (maybe): verify these quantities with outputs from Haskell

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -1,17 +1,16 @@
--- ---
title: "A Game of Permutations, Part 2" title: "A Game of Permutations, Part 2"
description: | description: |
Permutohedra and some very large graphs Notes on permutohedra and some very large graphs.
format: format:
html: html:
html-math-method: katex html-math-method: katex
jupyter: python3 jupyter: python3
date: "2022-01-18" date: "2022-01-18"
date-modified: "2025-07-04" date-modified: "2025-07-06"
categories: categories:
- graph theory - graph theory
- group theory - group theory
- sorting algorithms
--- ---
```{python} ```{python}
@ -36,27 +35,29 @@ Cayley Graphs
------------- -------------
For a given generating set, we can assign every element in the group it generates to a vertex in a graph. For a given generating set, we can assign every element in the group it generates to a vertex in a graph.
Starting with each of the generators, we draw arrows from one vertex to the other when Starting with each of the generators, we draw edges from one vertex to another when
the product of the initial vertex and a generator (in that order) is the product vertex. the product of the initial vertex and a generator (in that order) is the product vertex.
If we continue until there are no more arrows to draw, the resulting figure is known as a This process continues until there are no more arrows to draw.
[Cayley graph](https://mathworld.wolfram.com/CayleyGraph.html). The resulting figure is known as a [Cayley graph](https://mathworld.wolfram.com/CayleyGraph.html)[^1].
Owing to the way in which they are generated, Cayley graphs have a few useful properties as graphs. [^1]: The construction implies a labelling of edges by its generating set and a labelling
of vertices by the generated elements.
It is also common to describe an unlabelled graph as "Cayley" if it could
be generated by this procedure.
Owing to the way in which they are defined, Cayley graphs have a few useful properties as graphs.
At every vertex, we have as many outward edges as we do generators in the generating set, At every vertex, we have as many outward edges as we do generators in the generating set,
so the outward (and in fact, inward) degree of each vertex is the same. so the outward (and in fact, inward) degree of each vertex is the same.
In other words, it is a regular graph. In other words, it is a regular graph.
More than that, it is vertex-transitive, since labelling a single vertex's outward edges More than that, it is [vertex-transitive](https://mathworld.wolfram.com/Vertex-TransitiveGraph.html),
will label that of the entire graph. since labelling a single vertex's outward edges will label that of the entire graph.
Cayley graphs can take a wide variety of shapes, which depend on the generating set used. Cayley graphs depend on the generating set used, so they can take a wide variety of shapes.
Their construction implies a labelling of vertices by permutations and an edge labelling
indicative of its generating set, but they can just as easily be abstract graphs separate
from the procedure that was used to generate them.
Here are a few examples of Cayley graphs made from elements of $S_4$: Here are a few examples of Cayley graphs made from elements of $S_4$:
![ ![
Left: $\{(1 ~ 3 ~ 2 ~ 4), (3 ~ 4), (1 ~ 4 ~ 2 ~ 3)\}$, cube graph <br> Left: $\{(1 ~ 3 ~ 2 ~ 4), (3 ~ 4), (1 ~ 4 ~ 2 ~ 3)\}$, cube graph <br>
Middle: $\{(1 ~ 2 ~ 3), (2 ~ 3 ~ 4)\}$ cuboctahedral graph <br> Middle: $\{(1 ~ 2 ~ 3), (2 ~ 3 ~ 4)\}$, cuboctahedral graph <br>
Right: $\{(2 ~ 3), (3 ~ 4), (2 ~ 3 ~ 4)\}$, octahedral graph <br> Right: $\{(2 ~ 3), (3 ~ 4), (2 ~ 3 ~ 4)\}$, octahedral graph <br>
Generating sets obtained from the previous MathWorld article. Generating sets obtained from the previous MathWorld article.
](./s4_cayley_graphs.png) ](./s4_cayley_graphs.png)
@ -70,10 +71,17 @@ However, if for every member of the generating set, we also include its inverse,
Graphs to Graphs Graphs to Graphs
---------------- ----------------
Since all 2-cycles are their own inverse, the generating sets which include only them produce undirected Cayley graphs. All 2-cycles are their own inverse, so generating sets which include only them
Furthermore, since the generating set can itself be thought of as a graph, produce undirected Cayley graphs.
Since this kind of generating set can itself be thought of as a graph,
we may consider an operation from graphs to graphs that maps a swap diagram to its Cayley graph. we may consider an operation from graphs to graphs that maps a swap diagram to its Cayley graph.
![
An example of this operation, denoted as $\exp$.
While the proper Cayley graphs for $(1 ~ 2)$ and $(3 ~ 4)$ are not shown (they are also 2-paths),
their product, the 4-cycle graph, is in the center.
](./exp_p2_oplus_p2.png)
I've taken to calling this operation the "graph exponential"[^1] because of its apparent relationship I've taken to calling this operation the "graph exponential"[^1] because of its apparent relationship
with the disjoint union. with the disjoint union.
Namely, it seems to be the case that $\exp( A \oplus B ) = \exp( A ) \times \exp( B )$, Namely, it seems to be the case that $\exp( A \oplus B ) = \exp( A ) \times \exp( B )$,
@ -82,17 +90,10 @@ Namely, it seems to be the case that $\exp( A \oplus B ) = \exp( A ) \times \exp
[^1]: Originally, I called this operation the "graph factorial", since it involves permutations [^1]: Originally, I called this operation the "graph factorial", since it involves permutations
and the number of vertices in the resulting graph grows factorially. and the number of vertices in the resulting graph grows factorially.
While I believe this is a better name, some images in this article retain the earlier A! notation.
[^2]: Graphs have many product structures, such as the tensor product and strong product. [^2]: Graphs have many product structures, such as the tensor product and strong product.
The Cartesian product is (categorically) more natural when paired with disjoint unions. The Cartesian product is (categorically) more natural when paired with disjoint unions.
![
An example of the graph exponential.
While the individual Cayley graphs for $(1 ~ 2)$ and $(3 ~ 4)$ are not shown (they are also 2-paths),
their (box) product, the 4-cycle graph, is in the center.
](./exp_p2_oplus_p2.png)
This operation is my own invention, so I am unsure whether or not This operation is my own invention, so I am unsure whether or not
it constitutes anything useful. it constitutes anything useful.
In fact, the possible graphs grow so rapidly that computing anything about the exponential In fact, the possible graphs grow so rapidly that computing anything about the exponential
@ -108,7 +109,8 @@ They are among the simplest graphs one can consider, and as we will see shortly,
Some Small Exponential Graphs Some Small Exponential Graphs
----------------------------- -----------------------------
Because of the difficulty in determining graph isomorphism, it is challenging for a computer to find a graph in an encyclopedia. Because of [the difficulty in determining graph isomorphism](https://en.wikipedia.org/wiki/Graph_isomorphism_problem),
it is challenging for a computer to find a graph in an encyclopedia.
Computers think of graphs as a list of vertices and their outward edges, Computers think of graphs as a list of vertices and their outward edges,
but this implementation faces inherent labelling issues. but this implementation faces inherent labelling issues.
These persist even if the graph is described as a list of (un)ordered pairs, These persist even if the graph is described as a list of (un)ordered pairs,
@ -119,12 +121,14 @@ I was able to locate a project named the
but it is only able to build a database simple connected graphs which but it is only able to build a database simple connected graphs which
can be queried by invariants (and is outdated since it uses Python 2). can be queried by invariants (and is outdated since it uses Python 2).
However, as visual objects, humans can compare graphs fairly easily -- the name means "drawing" after all. However, as visual objects, humans can compare graphs fairly easily
Exponentials of 3- and 4- graphs are neither so small as to be uninteresting nor so big as to be unparsable by humans. -- the name means "drawing" after all.
Exponentials of 3- and 4-graphs are neither so small as to be uninteresting
nor so big as to be unparsable by humans.
### Order 3 ### Order 3
<!-- TODO: Diagram contains old ! format -->
![&nbsp;](./exp_order_3.png) ![&nbsp;](./exp_order_3.png)
At this stage, we only really have two graphs to consider, since $P_3 = \bigstar_3$. At this stage, we only really have two graphs to consider, since $P_3 = \bigstar_3$.
@ -135,7 +139,7 @@ It is also apparent that $\exp( K_3 )$ is the utility graph, $K_{3,3}$.
![&nbsp;](./exp_p3_oplus_p2.png) ![&nbsp;](./exp_p3_oplus_p2.png)
We can again demonstrate the sum rule of the graph exponential with $\exp( P_3 \oplus P_2 )$. We can again demonstrate the sum rule of the graph exponential with $\exp( P_3 \oplus P_2 )$.
Simplifying, since we know $\exp( P_3 ) = C_6$, the expression is $C_6 \times P_2 = \text{Prism}_6$, Simplifying, since we know $\exp( P_3 ) = C_6$, the result is $C_6 \times P_2 = \text{Prism}_6$,
the hexagonal prism graph. the hexagonal prism graph.
@ -147,8 +151,7 @@ Simplifying, since we know $\exp( P_3 ) = C_6$, the expression is $C_6 \times P_
![$\exp( \bigstar_4 )$](./exp_star4_networkx.png) ![$\exp( \bigstar_4 )$](./exp_star4_networkx.png)
::: :::
<!-- TODO: blank? --> ![&nbsp;](./exp_order_4.png)
![]()
With some effort, $\exp( P_4 )$ can be imagined as a projection of a 3D object, With some effort, $\exp( P_4 )$ can be imagined as a projection of a 3D object,
the [truncated octahedron](https://en.wikipedia.org/wiki/Truncated_octahedron). the [truncated octahedron](https://en.wikipedia.org/wiki/Truncated_octahedron).
@ -160,16 +163,19 @@ In fact, they are able to completely tessellate the $n-1$ dimensional subspace o
$\mathbb{R}^n$ where the coordinates sum to the $n-1$th triangular number. $\mathbb{R}^n$ where the coordinates sum to the $n-1$th triangular number.
Note that the previous graph in the sequence of $\exp(P_n)$, the hexagonal graph, Note that the previous graph in the sequence of $\exp(P_n)$, the hexagonal graph,
is visible in the truncated octahedron. is visible in the truncated octahedron.
This can be seen in the orthographic projection obtained by the map $(x,y,z,w) \mapsto (x,y,z)$. This corresponds to the projection $(x,y,z,w) \mapsto (x,y,z)$ over
the coordinates of the permutohedra.
Technically, there is a distinction between the Cayley graphs and permutohedra since their labellings differ. Technically, there is a distinction between the Cayley graphs and permutohedra
Both have edges generated by swaps, but in the latter case, there is a uniform since their labellings differ.
Euclidean metric between two vertices. Both have edges generated by swaps, but in the latter case, the connected vertices are expected to be
separated by a certain Euclidean distance.
More information about the distinction can be found at this article on More information about the distinction can be found at this article on
[Wikimedia](https://commons.wikimedia.org/wiki/Category:Permutohedron_of_order_4_%28raytraced%29#Permutohedron_vs._Cayley_graph)[^3]. [Wikimedia](https://commons.wikimedia.org/wiki/Category:Permutohedron_of_order_4_%28raytraced%29#Permutohedron_vs._Cayley_graph)[^3].
[^3]: Actually, if one considers a *right* Cayley graph, where each generator is right-multiplied [^3]: Actually, if one considers a *right* Cayley graph, where each generator is right-multiplied
to the permutation at a node rather than left-multiplied, then a true correspondence is obtained. to the permutation at a node rather than left-multiplied, then a true correspondence is obtained,
at least for order 4.
Meanwhile, $\exp( \bigstar_4 )$ is more difficult to identify, at least without rearranging its vertices. Meanwhile, $\exp( \bigstar_4 )$ is more difficult to identify, at least without rearranging its vertices.
It turns out to be isomorphic to the [Nauru graph](https://mathworld.wolfram.com/NauruGraph.html), It turns out to be isomorphic to the [Nauru graph](https://mathworld.wolfram.com/NauruGraph.html),
@ -179,7 +185,8 @@ Notably, whereas the graph isomorphic to the permutohedron is obviously a spheri
The Nauru graph also belongs to the family of The Nauru graph also belongs to the family of
[permutation star graphs](https://mathworld.wolfram.com/PermutationStarGraph.html) [permutation star graphs](https://mathworld.wolfram.com/PermutationStarGraph.html)
$PS_n$ (*n* = 4), which also includes the hexagonal graph (*n* = 3). $PS_n$ (*n* = 4), which also includes the hexagonal graph (*n* = 3).
The MathWorld article confirms a correspondence, stating graphs of this form are generated by pairwise swaps. The MathWorld article confirms some kind of correspondence, stating graphs of this form
are generated by pairwise swaps.
My attempts at finding a graph isomorphic to $\exp( K_4 )$ have thus far ended in failure. My attempts at finding a graph isomorphic to $\exp( K_4 )$ have thus far ended in failure.
It is certainly *not* isomorphic to $K_{4,4}$, since this graph has 8 vertices, It is certainly *not* isomorphic to $K_{4,4}$, since this graph has 8 vertices,
@ -201,16 +208,42 @@ I also have great confidence in the sequences I found for $\exp( K_n )$.
#### Edge Counts #### Edge Counts
Despite knowing how many vertices there are ($n!$, the order of the symmetric group), we don't necessarily know how many edges there are. Despite knowing how many vertices there are ($n!$, the order of the symmetric group),
we don't necessarily know how many edges there are.
| *n* | $\#E(\exp( P_n ))$ | $\#E(\exp( \bigstar_n ))$ | $\#E(\exp( K_n ))$ | ```{python}
|------|--------------------|---------------------------|--------------------| #| echo: false
| 3 | 6 | 6 | 9 | #| classes: plain
| 4 | 36 | 36 | 72 |
| 5 | 240 | 240 | 600 | Markdown(tabulate(
| 6 | 1800 | 1800 | 5400 | [
| 7 | 15120 | 15120 | 52920 | [i, pathG.edge_count, starG.edge_count, completeG.edge_count]
| Rule | Second column of Lah numbers $L(n,2) = n!{(n-1)(n-2) \over 4}$ [OEIS A001286](http://oeis.org/A001286) | Same as previous | $n!{n(n-1) \over 4}$ [OEIS 001809](http://oeis.org/A001809) | for i in range(3, 8)
for pathG, starG, completeG in (
[path.data[i], star.data[i], complete.data[i]],
)
] + [
[
"Sequence",
"Second column of Lah numbers <br> [OEIS A001286](http://oeis.org/A001286)",
"Same as previous",
"[OEIS 001809](http://oeis.org/A001809)",
],
[
"Rule",
r"$L(n,2) = n!{(n-1)(n-2) \over 4}$",
"",
r"$n!{n(n-1) \over 4}$"
]
],
headers=[
"*n*",
r"$\#E(\exp( P_n ))$",
r"$\#E(\exp( \bigstar_n ))$",
r"$\#E(\exp( K_n ))$"
]
))
```
#### Radius and Distance Classes #### Radius and Distance Classes
@ -218,56 +251,68 @@ Despite knowing how many vertices there are ($n!$, the order of the symmetric gr
The radius of a graph is the smallest possible distance which separates two maximally-separated vertices. The radius of a graph is the smallest possible distance which separates two maximally-separated vertices.
Due to vertex transitivity, the greatest distance between two vertices is the same for every vertex. Due to vertex transitivity, the greatest distance between two vertices is the same for every vertex.
| *n* | $r(\exp( P_n ))$ | $r(\exp( \bigstar_n ))$ | $r(\exp( K_n ))$ | ```{python}
|------|------------------|-------------------------|------------------| #| echo: false
| 3 | 3 | 3 | 2 | #| classes: plain
| 4 | 6 | 4 | 3 |
| 5 | 10 | 6 | 4 |
| 6 | 15 | 7 | 5 |
| 7 | 21 | 9 | 6 |
| Rule | Triangular numbers $\Delta_{n-1} = {n(n-1) \over 2}$ [OEIS A00021](http://oeis.org/A000217) | Integers not congruent to 2 (mod 3) $\lfloor {n-1 \over 2} \rfloor + n -\ 1$ [OEIS A032766](http://oeis.org/A032766) | *n* - 1 |
More information can be gathered about distances on the graph than these reductive quantities. Markdown(tabulate(
If a vertex is distinguished and the remaining vertices are partitioned into classes by their distances from it, [
then the size of each class will be the same for every vertex. [i, len(pathG), len(starG), len(completeG)]
for i in range(3, 8)
for pathG, starG, completeG in (
[path.data[i].distance_classes, star.data[i].distance_classes, complete.data[i].distance_classes],
)
] + [
[
"Sequence",
"Triangular numbers <br> [OEIS A000217](http://oeis.org/A000217)",
"Integers not congruent to 2 (mod 3) <br> [OEIS A032766](http://oeis.org/A032766)",
"*n* - 1"
],
[
"Rule",
r"$\Delta_{n-1} = {n(n-1) \over 2}$",
r"$\lfloor {n-1 \over 2} \rfloor + n -\ 1$"
]
],
headers=[
"*n*",
r"$r(\exp( P_n ))$",
r"$r(\exp( \bigstar_n ))$",
r"$r(\exp( K_n ))$"
]
))
```
These quantities are somewhat reductive.
If a vertex is distinguished, the remaining vertices may be partitioned into classes by their
distance from it.
Including the vertex itself (which is distance 0 away), there will be $r + 1$ such classes, Including the vertex itself (which is distance 0 away), there will be $r + 1$ such classes,
where r is the radius. where *r* is the radius.
These classes are the same for every vertex due to transitivity.
In the case of these graphs, they are a partition of the factorial numbers. In the case of these graphs, they are a partition of the factorial numbers.
```{python} ```{python}
#| echo: false #| echo: false
#| classes: plain #| classes: plain
mahonian = [
[1, 2, 2, 1],
[1, 3, 5, 6, 5, 3, 1],
[1, 4, 9, 15, 20, 22, 20, 15, 9, 4, 1],
[1, 5, 14, 29, 49, 71, 90, 101, 101, 90, 71, 49, 29, 14, 5, 1],
[1, 6, 20, 49, 98, 169, 259, 359, 455, 531, 573, 573, 531, 455, 359, 259, 169, 98, 49, 20, 6, 1],
]
whitney_second_kind = [
[1, 2, 2, 1],
[1, 3, 6, 9, 5],
[1, 4, 12, 30, 44, 26, 3],
[1, 5, 20, 70, 170, 250, 169, 35],
[1, 6, 30, 135, 460, 1110, 1689, 1254, 340, 15],
]
stirling_second_kind = [
[1, 3, 2],
[1, 6, 11, 6],
[1, 10, 35, 50, 24],
[1, 15, 85, 225, 274, 120],
[1, 21, 175, 735, 1624, 1764, 720],
]
half_break = lambda x: str(x[:len(x) // 2])[:-1] + "<br>" + str(x[len(x) // 2:])[1:] half_break = lambda x: str(x[:len(x) // 2])[:-1] + "<br>" + str(x[len(x) // 2:])[1:]
Markdown(tabulate( Markdown(tabulate(
[ [
[i, j if i <= 5 else half_break(j), k, l] [i, pathG if i <= 5 else half_break(pathG), starG, completeG]
for i, j, k, l in zip(range(3,8), mahonian, whitney_second_kind, stirling_second_kind) for i in range(3, 8)
for pathG, starG, completeG in (
[path.data[i].distance_classes, star.data[i].distance_classes, complete.data[i].distance_classes],
)
] + [
[
"Sequence",
"Mahonian numbers <br> [OEIS A008302](http://oeis.org/A008302)",
"Whitney numbers of the second kind (star poset) <br> [OEIS A007799](http://oeis.org/A007799)",
"Stirling numbers of the first kind <br> [OEIS A132393](http://oeis.org/A132393)"
]
], ],
headers=[ headers=[
"*n*", "*n*",
@ -278,9 +323,13 @@ Markdown(tabulate(
)) ))
``` ```
I am certain that the appearance of the Stirling numbers here is legitimate, since these numbers count the number of permutations of *n* objects with *k* disjoint cycles. I am certain that the appearance of the Stirling numbers here is legitimate,
Obviously, the identity element is distance 1 from all 2-cycles since they are all in the generating set; likewise, all 3-cycles are distance 2 from the identity (but distance 1 from the 2-cycles), and so on until the entire graph has been mapped. since these numbers count the number of permutations of *n* objects with *k* disjoint cycles.
The shapes induced by these classes were used to create the diagrams of $\exp( K_3 )$ and $\exp( K_4 )$ above. Obviously, the identity element is distance 1 from all 2-cycles since they are all in the generating set;
likewise, all 3-cycles are distance 2 from the identity (but distance 1 from the 2-cycles),
and so on until the entire graph has been mapped.
The shapes induced by these classes were used to create the diagrams
of $\exp( K_3 )$ and $\exp( K_4 )$ above.
#### Spectrum #### Spectrum
@ -299,7 +348,7 @@ Markdown(tabulate(
[i, pathG.to_markdown(), starG.to_markdown(), completeG.to_markdown()] [i, pathG.to_markdown(), starG.to_markdown(), completeG.to_markdown()]
for i in range(3, 9) for i in range(3, 9)
for pathG, starG, completeG in ( for pathG, starG, completeG in (
[path.path_spectra[i], star.star_spectra[i], complete.complete_spectra[i]], [path.data[i].spectrum, star.data[i].spectrum, complete.data[i].spectrum],
) )
], ],
headers=[ headers=[
@ -315,8 +364,9 @@ From what I have been able to identify, the spectrum of an exponential graph is
by which I mean that the characteristic polynomial is even. by which I mean that the characteristic polynomial is even.
This has been the case for all graphs I have tried testing, even outside these graph families. This has been the case for all graphs I have tried testing, even outside these graph families.
Since all eigenvalues of $\exp( \bigstar_n )$ calculated are integers, it appears they are integral graphs, Since all eigenvalues of $\exp( \bigstar_n )$ calculated are integers,
a fact of which I am reasonably sure because of the correspondence to permutation star graphs. it appears they are integral graphs, a fact of which I am reasonably sure
because of the aforementioned correspondence to permutation star graphs.
Additionally, the eigenvalues are very conveniently the integers up to $n-1$ and down to $-n+1$. Additionally, the eigenvalues are very conveniently the integers up to $n-1$ and down to $-n+1$.
Unfortunately, despite the ease of reading the eigenvalues themselves, Unfortunately, despite the ease of reading the eigenvalues themselves,
there isn't an OEIS entry for the multiplicities. there isn't an OEIS entry for the multiplicities.
@ -326,7 +376,7 @@ If this is truly the sequence being generated, it means there is a 1:1 correspon
these orderings and a basis of the nullspace of the adjacency matrix. these orderings and a basis of the nullspace of the adjacency matrix.
It seems to be the case that $\exp( K_n )$ are also integral graphs. It seems to be the case that $\exp( K_n )$ are also integral graphs.
Perplexingly, the multiplicities for each of the eigenvalues appear to be perfect powers. Perplexingly, the multiplicities for each of the eigenvalues appear to mostly be perfect powers.
This is the case until n = 8, which ruins the pattern because neither of This is the case until n = 8, which ruins the pattern because neither of
$9864 = 2^3 \cdot 3^2 \cdot 137$ or $6125 = 5^3 \cdot 7^2$ are perfect powers. $9864 = 2^3 \cdot 3^2 \cdot 137$ or $6125 = 5^3 \cdot 7^2$ are perfect powers.
I find both this and the fact that such a large prime appears among the factorization I find both this and the fact that such a large prime appears among the factorization
@ -380,8 +430,9 @@ While this is a fascinating topic unto itself, this post is already long enough,
::: :::
### [Heap's Algorithm](https://en.wikipedia.org/wiki/Heap%27s_algorithm)[^1] ### [Heap's Algorithm](https://en.wikipedia.org/wiki/Heap%27s_algorithm)
:::: {}
::: {layout-ncol="3"} ::: {layout-ncol="3"}
![$P_5$](heap/heap_path_5.png) ![$P_5$](heap/heap_path_5.png)
@ -396,7 +447,8 @@ While this is a fascinating topic unto itself, this post is already long enough,
![$K_6$](heap/heap_k_6.png) ![$K_6$](heap/heap_k_6.png)
::: :::
[^5]: GHC's `Data.List.permutations` is slightly different from Heap's algorithm as displayed on Wikipedia Note: GHC's `Data.List.permutations` is slightly different from Heap's algorithm as displayed on Wikipedia
::::
Closing Closing
@ -423,8 +475,8 @@ Remember, as raw bitmaps, these files are on the order of *gigabytes* big.
On a much weaker computer than I used to render the images, merely opening my file explorer On a much weaker computer than I used to render the images, merely opening my file explorer
to the folder containing *the folder containing* the images to the folder containing *the folder containing* the images
caused its all-too-eager thumbnailer to run. caused its all-too-eager thumbnailer to run.
It started to consume all of my system resources, crashing all of my browser's tabs, This started consuming all of my system resources, crashed all of my browser's tabs,
distorting audio, and locking up the computer. distorted audio, and finally locked up the computer.
Despite this, PNG is a wonderful format that is able to compress them down to just 4MB, Despite this, PNG is a wonderful format that is able to compress them down to just 4MB,
which demonstrates just how sparse these matrices are. which demonstrates just how sparse these matrices are.
@ -439,8 +491,12 @@ Graph diagrams made with GeoGebra and NetworkX (GraphViz).
### Additional Links ### Additional Links
- [Whitney Numbers of the Second Kind for the Star Poset (Paper from ScienceDirect)](https://www.sciencedirect.com/science/article/pii/S0195669813801278) - [Whitney Numbers of the Second Kind for the Star Poset (
Paper from ScienceDirect
)](https://www.sciencedirect.com/science/article/pii/S0195669813801278)
- This article includes a section about representing a list of generators as a graph, - This article includes a section about representing a list of generators as a graph,
making me wonder if someone has tried defining this operation before making me wonder if someone has tried defining this operation before
- [Whitney Numbers (Josh Cooper's Mathpages)](https://people.math.sc.edu/cooper/graph.html) - [Whitney Numbers (Josh Cooper's Mathpages)](https://people.math.sc.edu/cooper/graph.html)
- [The Many Faces of the Nauru Graph (Blogpost by David Eppstein)](https://11011110.github.io/blog/2007/12/12/many-faces-of.html) - [
The Many Faces of the Nauru Graph (Blogpost by David Eppstein)
](https://11011110.github.io/blog/2007/12/12/many-faces-of.html)