Skip to content

Commit

Permalink
sagemathgh-38725: fix issue in edge_cut
Browse files Browse the repository at this point in the history
    
Fixes sagemath#38713.

We ensure that all algorithms return edges with label when
`algorithm="LP"`.

### 📝 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,
-->
<!-- - sagemath#12345: short description why this is a dependency -->
<!-- - sagemath#34567: ... -->
    
URL: sagemath#38725
Reported by: David Coudert
Reviewer(s): Kwankyu Lee
  • Loading branch information
Release Manager committed Oct 5, 2024
2 parents 6c5c30f + fffb320 commit 92cb1dc
Showing 1 changed file with 8 additions and 7 deletions.
15 changes: 8 additions & 7 deletions src/sage/graphs/generic_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -7512,7 +7512,7 @@ def edge_cut(self, s, t, value_only=True, use_edge_labels=False, vertices=False,
sage: g.edge_cut(1, 2, value_only=True, algorithm='LP') # needs sage.numerical.mip
3

:issue:`12797`::
Check that :issue:`12797` and :issue:`38713` are fixed::

sage: G = Graph([(0, 3, 1), (0, 4, 1), (1, 2, 1), (2, 3, 1), (2, 4, 1)])
sage: G.edge_cut(0, 1, value_only=False, use_edge_labels=True)
Expand All @@ -7521,7 +7521,7 @@ def edge_cut(self, s, t, value_only=True, use_edge_labels=False, vertices=False,
sage: G.edge_cut(0, 1, value_only=False, use_edge_labels=True)
[1, [(2, 1, 1)]]
sage: G.edge_cut(0, 1, value_only=False, use_edge_labels=True, algorithm='LP') # needs sage.numerical.mip
(1, [(2, 1)])
(1, [(2, 1, 1)])
"""
self._scream_if_not_simple(allow_loops=True)
if vertices:
Expand Down Expand Up @@ -7574,9 +7574,10 @@ def weight(x):
# frozensets otherwise
if g.is_directed():
def good_edge(e):
return e
return (e[0], e[1])
else:
good_edge = frozenset
def good_edge(e):
return frozenset((e[0], e[1]))

# Some vertices belong to part 1, others to part 0
p.add_constraint(v[s], min=0, max=0)
Expand All @@ -7589,15 +7590,15 @@ def good_edge(e):

# Adjacent vertices can belong to different parts only if the
# edge that connects them is part of the cut
for x, y in g.edge_iterator(labels=None):
for x, y in g.edge_iterator(labels=False):
p.add_constraint(v[x] + b[good_edge((x, y))] - v[y], min=0)

else:
# we minimize the number of edges
p.set_objective(p.sum(weight(w) * b[good_edge((x, y))] for x, y, w in g.edge_iterator()))
# Adjacent vertices can belong to different parts only if the
# edge that connects them is part of the cut
for x, y in g.edge_iterator(labels=None):
for x, y in g.edge_iterator(labels=False):
p.add_constraint(v[x] + b[good_edge((x, y))] - v[y], min=0)
p.add_constraint(v[y] + b[good_edge((x, y))] - v[x], min=0)

Expand All @@ -7612,7 +7613,7 @@ def good_edge(e):
return obj

answer = [obj]
answer.append([e for e in g.edge_iterator(labels=False) if b[good_edge(e)]])
answer.append([e for e in g.edge_iterator(labels=True) if b[good_edge(e)]])

if vertices:
v = p.get_values(v, convert=bool, tolerance=integrality_tolerance)
Expand Down

0 comments on commit 92cb1dc

Please sign in to comment.