Skip to content

Commit

Permalink
gh-38175: Implemented generators for Staircase graph, Biwheel graph a…
Browse files Browse the repository at this point in the history
…nd Truncated biwheel graph

    
<!-- ^ Please provide a concise and informative title. -->
This PR adds generators for Staircase graph, Biwheel graph and Truncated
biwheel graph.
<!-- ^ Don't put issue numbers in the title, do this in the PR
description below. -->
<!-- ^ For example, instead of "Fixes #12345" use "Introduce new method
to calculate 1 + 2". -->
<!-- v Describe your changes below in detail. -->
This PR introduces new static methods, specifically `StaircaseGraph`,
`BiwheelGraph` and `TruncatedBiwheelGraph`, that consider a/ an
(constrained) integer *n* as the input and return the respective graph
of order *2n*. This shall also include the required documentation
concerning the same.
<!-- v Why is this change required? What problem does it solve? -->
It adds some new features, that is $-$ generators for Staircase graph,
Biwheel graph and Truncated biwheel graph.
<!-- v If this PR resolves an open issue, please link to it here. For
example, "Fixes #12345". -->
Fixes #38172.


### 📝 Checklist

<!-- Put an `x` in all the boxes that apply. -->

- [x] The title is concise and informative.
- [x] The description explains in detail what this PR is about.
- [x] I have linked a relevant issue or discussion.
- [x] I have created tests covering the changes.
- [x] I have updated the documentation and checked the documentation
preview.

### ⌛ Dependencies

<!-- List all open PRs that this PR logically depends on. For example,
-->
Nothing as of now (up to my knowledge).
<!-- - #12345: short description why this is a dependency -->
<!-- - #34567: ... -->

cc: @dcoudert.
    
URL: #38175
Reported by: Janmenjaya Panda
Reviewer(s): David Coudert, Janmenjaya Panda
  • Loading branch information
Release Manager committed Aug 2, 2024
2 parents ba8126d + 554de27 commit e37e378
Show file tree
Hide file tree
Showing 3 changed files with 331 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/doc/en/reference/references/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4396,6 +4396,10 @@ REFERENCES:
.. [LM2018] \A. Lauve, M. Mastnak. *Bialgebra coverings and transfer
of structure*. Preprint, :arxiv:`1803.02691`.
.. [LM2024] C.L. Lucchesi, U.S.R. Murty. *Perfect Matchings: A Theory of
Matching Covered Graphs*. Algorithms and Computation in Mathematics.
Springer Cham, 1st edition, 2024, :doi:`10.1007/978-3-031-47504-7`.
.. [LMR2010] \N. Linial, R. Meshulam and M. Rosenthal, "Sum complexes
-- a new family of hypertrees", Discrete & Computational
Geometry, 2010, Volume 44, Number 3, Pages 622-636
Expand Down
318 changes: 318 additions & 0 deletions src/sage/graphs/generators/families.py
Original file line number Diff line number Diff line change
Expand Up @@ -4424,3 +4424,321 @@ def CubeConnectedCycle(d):
G.add_edge((x, y), (x ^ (1 << y), y))

return G


def StaircaseGraph(n):
r"""
Return a staircase graph with `2n` nodes
For `n \geq 3`, the staircase graph of order `2n` is the graph obtained
from the ladder graph of order `2n - 2`, i.e., ``graphs.LadderGraph(n - 1)``
by introducing two new nodes `2n - 2` and `2n - 1`, and then joining the
node `2n - 2` with `0` and `n - 1`, the node `2n - 1` with `n - 2` and
`2n - 3`, and the nodes `2n - 2` and `2n - 1` with each other.
Note that ``graphs.StaircaseGraph(4)`` is also known as the ``Bicorn
graph``. It is the only brick that has a unique `b`-invariant edge.
PLOTTING:
Upon construction, the position dictionary is filled to override
the spring-layout algorithm. By convention, each staircase graph will be
displayed horizontally, with the first `n - 1` nodes displayed from left to
right on the top horizontal line, the second `n - 1` nodes displayed from
left to right on the middle horizontal line, and the last two nodes
displayed at the bottom two corners.
INPUT:
- ``n`` -- an integer at least 3; number of nodes is `2n`
OUTPUT:
- ``G`` -- a staircase graph of order `2n`; note that a
:class:`ValueError` is returned if `n < 3`
EXAMPLES:
Construct and show a staircase graph with 10 nodes::
sage: g = graphs.StaircaseGraph(5)
sage: g.show() # long time # needs sage.plot
Construct and show the Bicorn graph. Note that the edge `(1, 4)` is the
unique `b`-invariant edge::
sage: bicornGraph = graphs.StaircaseGraph(4)
sage: bicornGraph.show() # long time # needs sage.plot
Create several staircase graphs in a Sage graphics array::
sage: # needs sage.plots
sage: g = []
sage: j = []
sage: for i in range(9):
....: k = graphs.StaircaseGraph(i+3)
....: g.append(k)
sage: for i in range(3):
....: n = []
....: for m in range(3):
....: n.append(g[3*i + m].plot(vertex_size=50 - 4*(3*i+m), vertex_labels=False))
....: j.append(n)
sage: G = graphics_array(j)
sage: G.show() # long time
TESTS:
The input parameter must be an integer that is at least 3::
sage: G = graphs.StaircaseGraph(2)
Traceback (most recent call last):
...
ValueError: parameter n must be at least 3
REFERENCES:
- [LM2024]_
.. SEEALSO::
:meth:`~sage.graphs.graph_generators.GraphGenerators.LadderGraph`
AUTHORS:
- Janmenjaya Panda (2024-06-09)
"""
if n < 3:
raise ValueError("parameter n must be at least 3")

pos_dict = {
0: (0, 1),
n - 2: (n, 1),
2*n - 2: (0, -1),
2*n - 1: (n, -1)
}

edges = [
(0, n - 1),
(0, 2*n - 2),
(n - 2, 2*n - 3),
(n - 2, 2*n - 1),
(n - 1, 2*n - 2),
(2*n - 3, 2*n - 1),
(2*n - 2, 2*n - 1)
]

for v in range(1, n - 2):
pos_dict[v] = (v + 1, 1)
edges.append((v, v + n - 1))

for v in range(n - 1, 2*n - 2):
pos_dict[v] = (v - n + 2, 0)

G = Graph(2 * n, pos=pos_dict, name="Staircase graph")
G.add_edges(edges)
G.add_path(list(range(n - 1)))
G.add_path(list(range(n - 1, 2*n - 2)))
return G


def BiwheelGraph(n):
r"""
Return a biwheel graph with `2n` nodes
For `n \geq 4`, the biwheel graph of order `2n` is the planar
bipartite graph obtained from the cycle graph of order `2n - 2`, i.e.,
``graphs.CycleGraph(2*n - 2)`` (called the `rim` of the biwheel graph) by
introducing two new nodes `2n - 2` and `2n - 1` (called the *hubs* of the
biwheel graph), and then joining the node `2n - 2` with the odd indexed
nodes up to `2n - 3` and joining the node `2n - 1` with the even indexed
nodes up to `2n - 4`.
PLOTTING:
Upon construction, the position dictionary is filled to override
the spring-layout algorithm. By convention, each biwheel graph will be
displayed with the first (0) node at the right if `n` is even or
otherwise at an angle `\pi / (2n - 2)` with respect to the origin, with the
rest of the nodes up to `2n - 3` following in a counterclockwise manner.
Note that the last two nodes, i.e., the hubs `2n - 2` and `2n - 1` will
be displayed at the coordinates `(-1/3, 0)` and `(1/3, 0)` respectively.
INPUT:
- ``n`` -- an integer at least 4; number of nodes is `2n`
OUTPUT:
- ``G`` -- a biwheel graph of order `2n`; note that a
:class:`ValueError` is returned if `n < 4`
EXAMPLES:
Construct and show a biwheel graph with 10 nodes::
sage: g = graphs.BiwheelGraph(5)
sage: g.show() # long time # needs sage.plot
sage: g.is_planar()
True
sage: g.is_bipartite()
True
Create several biwheel graphs in a Sage graphics array::
sage: # needs sage.plots
sage: g = []
sage: j = []
sage: for i in range(9):
....: k = graphs.BiwheelGraph(i+4)
....: g.append(k)
sage: for i in range(3):
....: n = []
....: for m in range(3):
....: n.append(g[3*i + m].plot(vertex_size=50 - 4*(3*i+m), vertex_labels=False))
....: j.append(n)
sage: G = graphics_array(j)
sage: G.show() # long time
TESTS:
The input parameter must be an integer that is at least 4::
sage: G = graphs.BiwheelGraph(3)
Traceback (most recent call last):
...
ValueError: parameter n must be at least 4
REFERENCES:
- [LM2024]_
.. SEEALSO::
:meth:`~sage.graphs.graph_generators.GraphGenerators.WheelGraph`,
:meth:`~sage.graphs.graph_generators.GraphGenerators.TruncatedBiwheelGraph`
AUTHORS:
- Janmenjaya Panda (2024-06-09)
"""
if n < 4:
raise ValueError("parameter n must be at least 4")

angle_param = 0

if n % 2:
from math import pi
angle_param = pi / (2*n - 2)

G = Graph(2 * n, name="Biwheel graph")
pos_dict = G._circle_embedding(list(range(2*n - 2)), angle=angle_param, return_dict=True)
edges = []

from sage.rings.rational_field import QQ
pos_dict[2*n - 2] = (-QQ((1, 3)), 0)
pos_dict[2*n - 1] = (QQ((1, 3)), 0)

for i in range(2*n - 2):
if i % 2 == 0:
edges += [(i, 2*n - 1)]
else:
edges += [(i, 2*n - 2)]

G.set_pos(pos_dict)
G.add_cycle(list(range(2*n - 2)))
G.add_edges(edges)
return G


def TruncatedBiwheelGraph(n):
r"""
Return a truncated biwheel graph with `2n` nodes
For `n \geq 3`, the truncated biwheel graph of order `2n` is the graph
obtained from the path graph of order `2n - 2`, i.e.,
``graphs.PathGraph(2*n - 2)`` by introducing two new nodes `2n - 2` and
`2n - 1`, and then joining the node `2n - 2` with the odd indexed nodes
up to `2n - 3`, joining the node `2n - 1` with the even indexed nodes up to
`2n - 4` and adding the edges `(0, 2n - 2)` and `(2n - 3, 2n - 1)`.
PLOTTING:
Upon construction, the position dictionary is filled to override the
spring-layout algorithm. By convention, each truncated biwheel graph will
be displayed horizontally, with the first `2n - 2` nodes displayed from
left to right on the middle horizontal line and the nodes `2n - 2` and
`2n - 1` displayed at the top and the bottom central positions
respectively.
INPUT:
- ``n`` -- an integer at least 3; number of nodes is `2n`
OUTPUT:
- ``G`` -- a truncated biwheel graph of order `2n`; note that a
:class:`ValueError` is returned if `n < 3`
EXAMPLES:
Construct and show a truncated biwheel graph with 10 nodes::
sage: g = graphs.TruncatedBiwheelGraph(5)
sage: g.show() # long time # needs sage.plot
Create several truncated biwheel graphs in a Sage graphics array::
sage: # needs sage.plots
sage: g = []
sage: j = []
sage: for i in range(9):
....: k = graphs.TruncatedBiwheelGraph(i+3)
....: g.append(k)
sage: for i in range(3):
....: n = []
....: for m in range(3):
....: n.append(g[3*i + m].plot(vertex_size=50 - 4*(3*i+m), vertex_labels=False))
....: j.append(n)
sage: G = graphics_array(j)
sage: G.show() # long time
TESTS:
The input parameter must be an integer that is at least 3::
sage: G = graphs.TruncatedBiwheelGraph(2)
Traceback (most recent call last):
...
ValueError: parameter n must be at least 3
REFERENCES:
- [LM2024]_
.. SEEALSO::
:meth:`~sage.graphs.graph_generators.GraphGenerators.WheelGraph`,
:meth:`~sage.graphs.graph_generators.GraphGenerators.BiwheelGraph`
AUTHORS:
- Janmenjaya Panda (2024-06-09)
"""
if n < 3:
raise ValueError("parameter n must be at least 3")

pos_dict = {2*n - 2: (0, n), 2*n - 1: (0, -n)}
edges = [(0, 2*n - 2), (2*n - 3, 2*n - 1)]

for v in range(2*n - 2):
pos_dict[v] = (2*(v-n) + 3, 0)
if v % 2 == 0:
edges += [(v, 2*n - 1)]
else:
edges += [(v, 2*n - 2)]

G = Graph(2 * n, pos=pos_dict, name="Truncated biwheel graph")
G.add_path(list(range(2*n - 2)))
G.add_edges(edges)

return G
9 changes: 9 additions & 0 deletions src/sage/graphs/graph_generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ def wrap_name(x):
"BalancedTree",
"BarbellGraph",
"BilinearFormsGraph",
"BiwheelGraph",
"BubbleSortGraph",
"CaiFurerImmermanGraph",
"chang_graphs",
Expand Down Expand Up @@ -286,8 +287,10 @@ def wrap_name(x):
"SierpinskiGasketGraph",
"SquaredSkewHadamardMatrixGraph",
"SwitchedSquaredSkewHadamardMatrixGraph",
"StaircaseGraph",
"strongly_regular_graph",
"trees",
"TruncatedBiwheelGraph",
"nauty_gentreeg",
"triangulations",
"TuranGraph",
Expand Down Expand Up @@ -459,6 +462,9 @@ def wrap_name(x):
- Janmenjaya Panda (2024-05-26): added MoebiusLadderGraph
- Janmenjaya Panda (2024-06-09): added StaircaseGraph, BiwheelGraph and
TruncatedBiwheelGraph
Functions and methods
---------------------
Expand Down Expand Up @@ -2646,6 +2652,7 @@ def quadrangulations(self, order, minimum_degree=None, minimum_connectivity=None
BalancedTree = staticmethod(families.BalancedTree)
BarbellGraph = staticmethod(families.BarbellGraph)
BilinearFormsGraph = staticmethod(distance_regular.BilinearFormsGraph)
BiwheelGraph = staticmethod(families.BiwheelGraph)
BubbleSortGraph = staticmethod(families.BubbleSortGraph)
CaiFurerImmermanGraph = staticmethod(families.CaiFurerImmermanGraph)
chang_graphs = staticmethod(families.chang_graphs)
Expand Down Expand Up @@ -2700,10 +2707,12 @@ def quadrangulations(self, order, minimum_degree=None, minimum_connectivity=None
SierpinskiGasketGraph = staticmethod(families.SierpinskiGasketGraph)
SquaredSkewHadamardMatrixGraph = staticmethod(families.SquaredSkewHadamardMatrixGraph)
SwitchedSquaredSkewHadamardMatrixGraph = staticmethod(families.SwitchedSquaredSkewHadamardMatrixGraph)
StaircaseGraph = staticmethod(families.StaircaseGraph)
strongly_regular_graph = staticmethod(strongly_regular_db.strongly_regular_graph)
TabacjnGraph = staticmethod(families.TabacjnGraph)
TadpoleGraph = staticmethod(families.TadpoleGraph)
trees = staticmethod(families.trees)
TruncatedBiwheelGraph = staticmethod(families.TruncatedBiwheelGraph)
nauty_gentreeg = staticmethod(families.nauty_gentreeg)
TuranGraph = staticmethod(families.TuranGraph)
UstimenkoGraph = staticmethod(distance_regular.UstimenkoGraph)
Expand Down

0 comments on commit e37e378

Please sign in to comment.