Skip to content

Commit

Permalink
sagemathgh-39065: Implemented methods concerning bricks and braces of…
Browse files Browse the repository at this point in the history
… a matching covered graph

    
<!-- ^ Please provide a concise and informative title. -->
The objective of this issue is to implement the methods pertaining to
the bricks and brace of a matching covered graph.

<!-- ^ Don't put issue numbers in the title, do this in the PR
description below. -->
<!-- ^ For example, instead of "Fixes sagemath#12345" use "Introduce new method
to calculate 1 + 2". -->
<!-- v Describe your changes below in detail. -->
More specifically, this PR aims to implement the following two methods:
<!-- - [ ] `bricks_and_braces()` | Return the list of (underlying simple
graph of) the bricks and braces of the (matching covered) graph. -->
- [x]  `is_brace()` | Check if the (matching covered) graph is a brace
- [x] `is_brick()` | Check if the (matching covered) graph is a brick.
<!-- - [ ] `number_of_braces()` | Return the number of braces. -->
<!-- - [ ] `number_of_bricks()` | Return the number of bricks. -->
<!-- - [ ] `number_of_petersen_bricks()` | Return the number of Petersen
bricks. -->
<!-- - [ ] `tight_cut_decomposition()` | Return a tight cut
decomposition. -->

<!-- v Why is this change required? What problem does it solve? -->
This PR shall address the methods related to bricks, braces and tight
cut decomposition of matching covered graphs.

<!-- v If this PR resolves an open issue, please link to it here. For
example, "Fixes sagemath#12345". -->
Fixes sagemath#38216.
Note that this issue fixes a small part of the mentioned issue.

### 📝 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
This PR depends on the PR sagemath#38742 and sagemath#38892.

<!-- List all open PRs that this PR logically depends on. For example,
-->
<!-- - sagemath#12345: short description why this is a dependency -->
<!-- - sagemath#34567: ... -->

cc: @dcoudert.
    
URL: sagemath#39065
Reported by: Janmenjaya Panda
Reviewer(s): David Coudert, Janmenjaya Panda, user202729
  • Loading branch information
Release Manager committed Jan 20, 2025
2 parents 5188024 + 9a95221 commit 548c79a
Show file tree
Hide file tree
Showing 2 changed files with 840 additions and 81 deletions.
39 changes: 14 additions & 25 deletions src/sage/graphs/matching.py
Original file line number Diff line number Diff line change
Expand Up @@ -877,7 +877,7 @@ def is_matching_covered(G, matching=None, algorithm='Edmonds', coNP_certificate=
sage: H = graphs.PathGraph(20)
sage: M = H.matching()
sage: H.is_matching_covered(matching=M, coNP_certificate=True)
(False, (1, 2, None))
(False, (2, 1, None))
TESTS:
Expand Down Expand Up @@ -1019,44 +1019,33 @@ def is_matching_covered(G, matching=None, algorithm='Edmonds', coNP_certificate=
if color[u]:
u, v = v, u

if M.has_edge(u, v):
H.add_edge(u, v)
else:
H.add_edge(v, u)
H.add_edge((u, v))
if next(M.neighbor_iterator(u)) == v:
H.add_edge((v, u))

# Check if H is strongly connected using Kosaraju's algorithm
def dfs(J, v, visited, orientation):
def dfs(v, visited, neighbor_iterator):
stack = [v] # a stack of vertices

while stack:
v = stack.pop()
visited.add(v)

if v not in visited:
visited[v] = True

if orientation == 'in':
for u in J.neighbors_out(v):
if u not in visited:
stack.append(u)

elif orientation == 'out':
for u in J.neighbors_in(v):
if u not in visited:
stack.append(u)
else:
raise ValueError('Unknown orientation')
for u in neighbor_iterator(v):
if u not in visited:
stack.append(u)

root = next(H.vertex_iterator())

visited_in = {}
dfs(H, root, visited_in, 'in')
visited_in = set()
dfs(root, visited_in, H.neighbor_in_iterator)

visited_out = {}
dfs(H, root, visited_out, 'out')
visited_out = set()
dfs(root, visited_out, H.neighbor_out_iterator)

for edge in H.edge_iterator():
u, v, _ = edge
if (u not in visited_in) or (v not in visited_out):
if (u not in visited_out) or (v not in visited_in):
if not M.has_edge(edge):
return (False, edge) if coNP_certificate else False

Expand Down
Loading

0 comments on commit 548c79a

Please sign in to comment.