Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added induced minor function to graph algorithms #36354

Merged
merged 9 commits into from
Oct 14, 2023

Conversation

saatvikraoIITGN
Copy link
Contributor

@saatvikraoIITGN saatvikraoIITGN commented Sep 28, 2023

Description

Fixes #36353

This pull request introduces the "induced_minor" function to the SageMath library for graph theory. The function allows users to find an induced minor isomorphic to a given target graph H in a graph G. It utilizes Mixed Integer Linear Programming (MILP) to solve this problem efficiently.

Motivation

The "induced_minor" function is a valuable addition to SageMath as it addresses the need to find induced minors, a fundamental concept in graph theory. Users often encounter scenarios where they need to identify an induced minor isomorphic to a specific target graph, and this function streamlines the process.

Issue: #36353
Documentation Issue: ----

Implementation

Logic

An existing minor function had several constraints for finding an induced minor isomorphic to a given target graph H in a graph`G:

  1. Representative Sets: Ensure that each vertex v in G represents a vertex h in H using binary variables rs[h, v].
  2. Connected Representative Sets: Enforce that the representative sets in G form a connected tree structure using binary variables edges[h, fuv] for edges (u, v) in G.
  3. Tree Structure: Ensure that the number of edges in the tree for each h in H is exactly one less than the cardinality of its representative set.
  4. Acyclic Trees: Maintain acyclic tree structures for representative sets using r_edges[h, (u, v)] variables and constraints.
  5. Edges Correspondence: Ensure that edges between representative sets in G correspond to edges in H using h_edges variables.

For induced minor, we just had to add an additional constraint:

  1. Induced Subgraph Condition: Checks for the existence of edges (h1, h2) in target graph H. If no such edge exists in H, it ensures that there is no edge between the representative sets of vertices h1 and h2 in graph G.

Algorithm and Complexity

The "induced_minor" function uses MILP to find the minor and follows the algorithm described in [KKT2006]. The complexity of this operation is discussed in the docstring.

Example Usage

The PR includes examples demonstrating how to use the "induced_minor" function to find induced minors isomorphic to specific target graphs in various scenarios.

Tests

The code includes tests to ensure the correctness of the "induced_minor" function. These tests cover different use cases, including scenarios where no induced minor exists.

Documentation

The documentation will be updated in a separate PR to include information about the new "induced_minor" function.

📝 Checklist

  • The title is concise, informative, and self-explanatory.
  • The description explains in detail what this PR is about.
  • I have linked the relevant issue Implement function for induced minor in graph #36353.
  • I have created tests covering the changes.
  • I will update the documentation in a separate PR, if required.

⌛ Dependencies

N/A (There are no open PRs that this PR depends on.)

Copy link
Contributor

@dcoudert dcoudert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this new functionality. However, to avoid unnecessary code duplication, it is better to add parameter induced (default to False) to method minor and, when true, to add the extra constraints to the MIP.

src/sage/graphs/graph.py Outdated Show resolved Hide resolved
src/sage/graphs/graph.py Outdated Show resolved Hide resolved
Copy link
Contributor

@dcoudert dcoudert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much better this way.

src/sage/graphs/graph.py Outdated Show resolved Hide resolved
src/sage/graphs/graph.py Outdated Show resolved Hide resolved
src/sage/graphs/graph.py Outdated Show resolved Hide resolved
src/sage/graphs/graph.py Outdated Show resolved Hide resolved
src/sage/graphs/graph.py Outdated Show resolved Hide resolved
src/sage/graphs/graph.py Show resolved Hide resolved
src/sage/graphs/graph.py Outdated Show resolved Hide resolved
src/sage/graphs/graph.py Outdated Show resolved Hide resolved
Copy link
Contributor

@dcoudert dcoudert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a few more remarks. Sorry for that.

src/sage/graphs/graph.py Outdated Show resolved Hide resolved
src/sage/graphs/graph.py Outdated Show resolved Hide resolved
src/sage/graphs/graph.py Outdated Show resolved Hide resolved
src/sage/graphs/graph.py Show resolved Hide resolved
src/sage/graphs/graph.py Outdated Show resolved Hide resolved
Copy link
Contributor

@dcoudert dcoudert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope these are my last comments. Sorry for all these Python style details.

src/sage/graphs/graph.py Outdated Show resolved Hide resolved
src/sage/graphs/graph.py Outdated Show resolved Hide resolved
src/sage/graphs/graph.py Outdated Show resolved Hide resolved
src/sage/graphs/graph.py Outdated Show resolved Hide resolved
Copy link
Contributor

@dcoudert dcoudert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately I cannot push in this branch, so I give you the diff of the changes that are required due to remaining trailing white spaces, coding style and more importantly doctest errors (check that using ./sage -t --long src/sage/graphs/graph.py).

In particular, we can call randint but not random.randint. Furthermore, the call to g.add_edge(random.randint(0, 5), i) may raise an error when the value r of the random number is equal to i. Indeed, the graph g does not allow loops. Instead, we can use a call to g.add_vertex() which returns a new vertex with an unused integer label.

diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py
index cea6ff99ba..4db0b324f2 100644
--- a/src/sage/graphs/graph.py
+++ b/src/sage/graphs/graph.py
@@ -4911,7 +4911,7 @@ class Graph(GenericGraph):
         been merged to create a new graph `G'`, this new graph contains `H` as a
         subgraph.
 
-        When parameter ``induced`` is ``True``, this method returns an induced minor 
+        When parameter ``induced`` is ``True``, this method returns an induced minor
         isomorphic to `H`, if it exists.
 
         We say that a graph `G` has an induced `H`-minor (or that it has a
@@ -4941,7 +4941,8 @@ class Graph(GenericGraph):
           :meth:`MixedIntegerLinearProgram.get_values`.
 
         - ``induced`` -- boolean (default: ``False``); if ``True``, returns an
-          induced minor isomorphic to `H` if it exists, and :class:`ValueError` otherwise.
+          induced minor isomorphic to `H` if it exists, and raises a
+          :class:`ValueError` otherwise.
 
         OUTPUT:
 
@@ -5001,21 +5002,24 @@ class Graph(GenericGraph):
             ...
             ValueError: This graph has no minor isomorphic to H !
 
-        Trying to find an induced minor for a graph with a C6 cycle::
+        Trying to find an induced minor isomorphic to `C_5` in a graph
+        containing an induced `C_6`::
 
-            sage: g = graphs.CycleGraph(6)              # Create a graph with 6 vertices forming a C6 cycle
-            sage: for i in random.randint(10, 30):
-            ....:     g.add_edge(random.randint(0, 5), i)
-            sage: h = graphs.CycleGraph(5)               # Create a graph with 5 vertices forming a C5 cycle
-            sage: L = g.minor(h, induced=True)                       
-            sage: gg = g.subgraph(flatten(L.values(), max_level = 1))         
-            sage: _ = [gg.merge_vertices(l) for l in L.values() if len(l)>1]
+            sage: g = graphs.CycleGraph(6)
+            sage: for i in range(randint(10, 30)):
+            ....:     g.add_edge(randint(0, 5), g.add_vertex())
+            sage: h = graphs.CycleGraph(5)
+            sage: L = g.minor(h, induced=True)
+            sage: gg = g.subgraph(flatten(L.values(), max_level=1))
+            sage: _ = [gg.merge_vertices(l) for l in L.values() if len(l) > 1]
             sage: gg.is_isomorphic(h)
             True
 
         TESTS::
-            
-            sage: # a graph `g` may have minor but no induced minor isomorphic to given graph `h`
+
+        A graph `g` may have a minor isomorphic to a given graph `h` but no
+        induced minor isomorphic to `h`::
+
             sage: g = Graph([(0, 1), (0, 2), (1, 2), (2, 3), (3, 4), (3, 5), (4, 5), (6, 5)])
             sage: h = Graph([(9, 10), (9, 11), (9, 12), (9, 13)])
             sage: l = g.minor(h, induced=False)
@@ -5024,11 +5028,14 @@ class Graph(GenericGraph):
             ...
             ValueError: This graph has no induced minor isomorphic to H !
 
+        Checking that the returned induced minor is isomorphic to the given
+        graph::
+
             sage: g = Graph([(0, 1), (0, 2), (1, 2), (2, 3), (3, 4), (3, 5), (4, 5), (6, 5)])
             sage: h = Graph([(7, 8), (8, 9), (9, 10), (10, 11)])
             sage: L = g.minor(h, induced=True)
-            sage: gg = g.subgraph(flatten(L.values(), max_level = 1))
-            sage: _ = [gg.merge_vertices(l) for l in L.values() if len(l)>1]
+            sage: gg = g.subgraph(flatten(L.values(), max_level=1))
+            sage: _ = [gg.merge_vertices(l) for l in L.values() if len(l) > 1]
             sage: gg.is_isomorphic(h)
             True
         """

Copy link
Contributor

@dcoudert dcoudert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect. Thanks.

@dcoudert
Copy link
Contributor

Can you edit the PR description to add at the top: Fixes #36353

This way, the PR will be automatically linked to the issue and both will be closed simultaneously. This greatly ease the work of the release manager. Thanks.

@saatvikraoIITGN saatvikraoIITGN changed the title added induced minor function to graph algorithms Fixes #36353: added induced minor function to graph algorithms Oct 10, 2023
@saatvikraoIITGN saatvikraoIITGN changed the title Fixes #36353: added induced minor function to graph algorithms added induced minor function to graph algorithms Fixes #36353 Oct 10, 2023
@saatvikraoIITGN saatvikraoIITGN changed the title added induced minor function to graph algorithms Fixes #36353 Fixes #36353 : added induced minor function to graph algorithms Oct 10, 2023
@saatvikraoIITGN saatvikraoIITGN changed the title Fixes #36353 : added induced minor function to graph algorithms added induced minor function to graph algorithms Oct 11, 2023
@saatvikraoIITGN
Copy link
Contributor Author

@dcoudert is the PR ready to merge?

@dcoudert
Copy link
Contributor

Yes. The release manager should merge it in the next beta release (or the following).

@vbraun vbraun merged commit de9da91 into sagemath:develop Oct 14, 2023
4 checks passed
@mkoeppe mkoeppe added this to the sage-10.2 milestone Oct 14, 2023
@fchapoton
Copy link
Contributor

this has broken our linters (trailing whitespaces and bad rst syntax)

@fchapoton fchapoton mentioned this pull request Oct 15, 2023
2 tasks
@dcoudert
Copy link
Contributor

Sorry for missing these issues when reviewing this PR.

vbraun pushed a commit to vbraun/sage that referenced this pull request Oct 17, 2023
    
Fix the broken linters again

broken just recently in` graphs/graph.py` sagemath#36354

### 📝 Checklist

- [x] The title is concise, informative, and self-explanatory.
- [x] The description explains in detail what this PR is about.
    
URL: sagemath#36461
Reported by: Frédéric Chapoton
Reviewer(s): Frédéric Chapoton, Kwankyu Lee
vbraun pushed a commit to vbraun/sage that referenced this pull request Oct 19, 2023
    
Fix the broken linters again

broken just recently in` graphs/graph.py` sagemath#36354

### 📝 Checklist

- [x] The title is concise, informative, and self-explanatory.
- [x] The description explains in detail what this PR is about.
    
URL: sagemath#36461
Reported by: Frédéric Chapoton
Reviewer(s): Frédéric Chapoton, Kwankyu Lee
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement function for induced minor in graph
5 participants