Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
trac #13917: IndependentSets class
Browse files Browse the repository at this point in the history
  • Loading branch information
nathanncohen committed Mar 13, 2014
1 parent f4fdcea commit cc8d994
Show file tree
Hide file tree
Showing 9 changed files with 445 additions and 15 deletions.
1 change: 1 addition & 0 deletions src/doc/en/reference/graphs/index.rst
Expand Up @@ -61,6 +61,7 @@ Libraries of algorithms

sage/graphs/graph_coloring
sage/graphs/cliquer
sage/graphs/independent_sets
sage/graphs/comparability
sage/graphs/line_graph
sage/graphs/spanning_tree
Expand Down
3 changes: 3 additions & 0 deletions src/module_list.py
Expand Up @@ -372,6 +372,9 @@ def uname_specific(name, value, alternative):
sources = ['sage/graphs/cliquer.pyx', 'sage/graphs/cliquer/cl.c'],
libraries = ['cliquer']),

Extension('sage.graphs.independent_sets',
sources = ['sage/graphs/independent_sets.pyx']),

Extension('sage.graphs.graph_decompositions.vertex_separation',
sources = ['sage/graphs/graph_decompositions/vertex_separation.pyx']),

Expand Down
3 changes: 3 additions & 0 deletions src/sage/graphs/base/static_dense_graph.pxd
@@ -0,0 +1,3 @@
include "sage/misc/binary_matrix.pxi"

cdef dict dense_graph_init(binary_matrix_t m, g, translation = ?)
1 change: 0 additions & 1 deletion src/sage/graphs/base/static_dense_graph.pyx
Expand Up @@ -40,7 +40,6 @@ Index
Functions
---------
"""
include "sage/misc/binary_matrix.pxi"

cdef dict dense_graph_init(binary_matrix_t m, g, translation = False):
r"""
Expand Down
64 changes: 51 additions & 13 deletions src/sage/graphs/graph.py
Expand Up @@ -4830,7 +4830,6 @@ def topological_minor(self, H, vertices = False, paths = False, solver=None, ver
v_repr = p.get_values(v_repr)
flow = p.get_values(flow)


for u,v in minor.edges(labels = False):
used = False
for C in H.edges(labels = False):
Expand All @@ -4856,16 +4855,33 @@ def topological_minor(self, H, vertices = False, paths = False, solver=None, ver

### Cliques

def cliques_maximal(self):
def def cliques_maximal(self, algorithm = "native"):
"""
Returns the list of all maximal cliques, with each clique represented
by a list of vertices. A clique is an induced complete subgraph, and a
maximal clique is one not contained in a larger one.
INPUT:
- ``algorithm`` -- can be set to ``"native"`` (default) to use Sage's
own implementation, or to ``"NetworkX"`` to use NetworkX'
implementation of the Bron and Kerbosch Algorithm [BroKer1973]_.
.. NOTE::
Currently only implemented for undirected graphs. Use to_undirected
to convert a digraph to an undirected graph.
This method sorts its output before returning it. If you prefer to
save the extra time, you can call
:class:`sage.graphs.independent_sets.IndependentSets` directly.
.. NOTE::
Sage's implementation of the enumeration of *maximal* independent
sets is not much faster than NetworkX' (expect a 2x speedup), which
is surprising as it is written in Cython. This being said, the
algorithm from NetworkX appears to be sligthly different from this
one, and that would be a good thing to explore if one wants to
improve the implementation.
ALGORITHM:
Expand All @@ -4882,21 +4898,37 @@ def cliques_maximal(self):
EXAMPLES::
sage: graphs.ChvatalGraph().cliques_maximal()
[[0, 1], [0, 4], [0, 6], [0, 9], [2, 1], [2, 3], [2, 6], [2, 8], [3, 4], [3, 7], [3, 9], [5, 1], [5, 4], [5, 10], [5, 11], [7, 1], [7, 8], [7, 11], [8, 4], [8, 10], [10, 6], [10, 9], [11, 6], [11, 9]]
[[0, 1], [0, 4], [0, 6], [0, 9], [1, 2], [1, 5], [1, 7], [2, 3],
[2, 6], [2, 8], [3, 4], [3, 7], [3, 9], [4, 5], [4, 8], [5, 10],
[5, 11], [6, 10], [6, 11], [7, 8], [7, 11], [8, 10], [9, 10], [9, 11]]
sage: G = Graph({0:[1,2,3], 1:[2], 3:[0,1]})
sage: G.show(figsize=[2,2])
sage: G.cliques_maximal()
[[0, 1, 2], [0, 1, 3]]
sage: C=graphs.PetersenGraph()
sage: C.cliques_maximal()
[[0, 1], [0, 4], [0, 5], [2, 1], [2, 3], [2, 7], [3, 4], [3, 8], [6, 1], [6, 8], [6, 9], [7, 5], [7, 9], [8, 5], [9, 4]]
[[0, 1], [0, 4], [0, 5], [1, 2], [1, 6], [2, 3], [2, 7], [3, 4],
[3, 8], [4, 9], [5, 7], [5, 8], [6, 8], [6, 9], [7, 9]]
sage: C = Graph('DJ{')
sage: C.cliques_maximal()
[[4, 0], [4, 1, 2, 3]]
[[0, 4], [4, 1, 2, 3]]
Comparing the two implementations::
sage: g = graphs.RandomGNP(20,.7)
sage: s1 = Set(map(Set, g.cliques_maximal(algorithm="NetworkX")))
sage: s2 = Set(map(Set, g.cliques_maximal(algorithm="native")))
sage: s1 == s2
True
"""
import networkx
return sorted(networkx.find_cliques(self.networkx_graph(copy=False)))
if algorithm == "native":
from sage.graphs.independent_sets import IndependentSets
return sorted(IndependentSets(self, maximal = True, complement = True))
elif algorithm == "NetworkX":
import networkx
return sorted(networkx.find_cliques(self.networkx_graph(copy=False)))
else:
raise ValueError("Algorithm must be equal to 'native' or to 'NetworkX'.")

cliques = deprecated_function_alias(5739, cliques_maximal)

Expand Down Expand Up @@ -5060,7 +5092,7 @@ def cliques_number_of(self, vertices=None, cliques=None):
{0: 1, 1: 1, 2: 1, 3: 1, 4: 2}
sage: E = C.cliques_maximal()
sage: E
[[4, 0], [4, 1, 2, 3]]
[[0, 4], [1, 2, 3, 4]]
sage: C.cliques_number_of(cliques=E)
{0: 1, 1: 1, 2: 1, 3: 1, 4: 2}
sage: F = graphs.Grid2dGraph(2,3)
Expand Down Expand Up @@ -5089,6 +5121,8 @@ def cliques_get_max_clique_graph(self, name=''):
edges between maximal cliques with common members in the original
graph.
For more information, see the :wikipedia:`Clique_graph`.
.. NOTE::
Currently only implemented for undirected graphs. Use to_undirected
Expand Down Expand Up @@ -5150,6 +5184,10 @@ def independent_set(self, algorithm = "Cliquer", value_only = False, reduction_r
Equivalently, an independent set is defined as the complement of a
vertex cover.
For more information, see the
:wikipedia:`Independent_set_(graph_theory)` and the
:wikipedia:`Vertex_cover`.
INPUT:
- ``algorithm`` -- the algorithm to be used
Expand Down Expand Up @@ -5523,7 +5561,7 @@ def cliques_vertex_clique_number(self, algorithm="cliquer", vertices=None,
{0: 2, 1: 4, 2: 4, 3: 4, 4: 4}
sage: E = C.cliques_maximal()
sage: E
[[4, 0], [4, 1, 2, 3]]
[[0, 4], [1, 2, 3, 4]]
sage: C.cliques_vertex_clique_number(cliques=E,algorithm="networkx")
{0: 2, 1: 4, 2: 4, 3: 4, 4: 4}
sage: F = graphs.Grid2dGraph(2,3)
Expand Down Expand Up @@ -5586,9 +5624,9 @@ def cliques_containing_vertex(self, vertices=None, cliques=None):
{0: [[4, 0]], 1: [[4, 1, 2, 3]], 2: [[4, 1, 2, 3]], 3: [[4, 1, 2, 3]], 4: [[4, 0], [4, 1, 2, 3]]}
sage: E = C.cliques_maximal()
sage: E
[[4, 0], [4, 1, 2, 3]]
[[0, 4], [1, 2, 3, 4]]
sage: C.cliques_containing_vertex(cliques=E)
{0: [[4, 0]], 1: [[4, 1, 2, 3]], 2: [[4, 1, 2, 3]], 3: [[4, 1, 2, 3]], 4: [[4, 0], [4, 1, 2, 3]]}
{0: [[0, 4]], 1: [[1, 2, 3, 4]], 2: [[1, 2, 3, 4]], 3: [[1, 2, 3, 4]], 4: [[0, 4], [1, 2, 3, 4]]}
sage: F = graphs.Grid2dGraph(2,3)
sage: X = F.cliques_containing_vertex()
sage: for v in sorted(X.iterkeys()):
Expand Down
14 changes: 14 additions & 0 deletions src/sage/graphs/independent_sets.pxd
@@ -0,0 +1,14 @@
from libc.stdint cimport uint32_t, uint64_t
include "sage/misc/binary_matrix.pxi"
include "sage/misc/bitset_pxd.pxi"
#include "sage/misc/bitset_pxd.pxi"

cdef class IndependentSets:
cdef binary_matrix_t g
cdef list vertices
cdef dict vertex_to_int
cdef int n
cdef int i
cdef int count_only
cdef int maximal

0 comments on commit cc8d994

Please sign in to comment.