Skip to content

Commit 3ed8572

Browse files
committed
reverse Cuthill-McKee algorithm for graphs
1 parent e249bef commit 3ed8572

File tree

1 file changed

+17
-4
lines changed

1 file changed

+17
-4
lines changed

src/sage/graphs/base/boost_graph.pyx

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,8 @@ cpdef bandwidth_heuristics(g, algorithm='cuthill_mckee') noexcept:
515515
Unfortunately, exactly computing the bandwidth is NP-hard (and an
516516
exponential algorithm is implemented in Sagemath in routine
517517
:func:`~sage.graphs.graph_decompositions.bandwidth.bandwidth`). Here, we
518-
implement two heuristics to find good orderings: Cuthill-McKee, and King.
518+
implement two heuristics to find good orderings: Cuthill-McKee, reverse
519+
Cuthill-McKee (also known as ``RCM``) and King.
519520
520521
This function works only in undirected graphs, and its running time is
521522
`O(md_{max}\log d_{max})` for the Cuthill-McKee ordering, and
@@ -527,7 +528,8 @@ cpdef bandwidth_heuristics(g, algorithm='cuthill_mckee') noexcept:
527528
- ``g`` -- the input Sage graph
528529
529530
- ``algorithm`` -- string (default: ``'cuthill_mckee'``); the heuristic used
530-
to compute the ordering among ``'cuthill_mckee'`` and ``'king'``
531+
to compute the ordering among ``'cuthill_mckee'``,
532+
``'reverse_cuthill_mckee'`` and ``'king'``
531533
532534
OUTPUT:
533535
@@ -542,6 +544,8 @@ cpdef bandwidth_heuristics(g, algorithm='cuthill_mckee') noexcept:
542544
(1, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
543545
sage: bandwidth_heuristics(graphs.GridGraph([3,3]))
544546
(3, [(0, 0), (1, 0), (0, 1), (2, 0), (1, 1), (0, 2), (2, 1), (1, 2), (2, 2)])
547+
sage: bandwidth_heuristics(graphs.GridGraph([3,3]), algorithm='reverse_cuthill_mckee')
548+
(3, [(2, 2), (1, 2), (2, 1), (0, 2), (1, 1), (2, 0), (0, 1), (1, 0), (0, 0)])
545549
sage: bandwidth_heuristics(graphs.GridGraph([3,3]), algorithm='king')
546550
(3, [(0, 0), (1, 0), (0, 1), (2, 0), (1, 1), (0, 2), (2, 1), (1, 2), (2, 2)])
547551
@@ -581,11 +585,16 @@ cpdef bandwidth_heuristics(g, algorithm='cuthill_mckee') noexcept:
581585
# Tests for errors and trivial cases
582586
if not isinstance(g, Graph):
583587
raise TypeError("the input must be a Sage Graph")
584-
if algorithm not in ['cuthill_mckee', 'king']:
588+
if algorithm not in ['cuthill_mckee', 'reverse_cuthill_mckee', 'king']:
585589
raise ValueError(f"unknown algorithm {algorithm!r}")
586590
if not g.num_edges():
587591
return (0, list(g))
588592

593+
cdef bint reverse = False
594+
if algorithm == 'reverse_cuthill_mckee':
595+
reverse = True
596+
algorithm = 'cuthill_mckee'
597+
589598
# These variables are automatically deleted when the function terminates.
590599
cdef BoostVecGraph g_boost
591600
cdef vector[v_index] result
@@ -601,8 +610,12 @@ cpdef bandwidth_heuristics(g, algorithm='cuthill_mckee') noexcept:
601610

602611
cdef int n = g.num_verts()
603612
cdef dict pos = {int_to_vertex[<int> result[i]]: i for i in range(n)}
604-
cdef int bandwidth = max([abs(pos[u] - pos[v]) for u, v in g.edge_iterator(labels=False)])
613+
cdef int bandwidth = max([abs(pos[u] - pos[v])
614+
for u, v in g.edge_iterator(labels=False)])
605615

616+
if reverse:
617+
return (bandwidth, [int_to_vertex[<int> result[i]]
618+
for i in range(n - 1, -1, -1)])
606619
return (bandwidth, [int_to_vertex[<int> result[i]] for i in range(n)])
607620

608621

0 commit comments

Comments
 (0)