summaryrefslogtreecommitdiff
blob: 1f24b5c5123f8149b6331f82adad1aa9b9dce71e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# HG changeset patch
# User Nathann Cohen <nathann.cohen@gmail.com>
# Date 1281583915 -28800
# Node ID 3bab2e5f2a633d4a8dafc234f1f9ac1efcc97f44
# Parent  cbafe93273bb7d6009768655eab131653b6a8449
trac 9567 -- Adds the method Graph.cycle_basis

diff -r cbafe93273bb -r 3bab2e5f2a63 sage/graphs/generic_graph.py
--- a/sage/graphs/generic_graph.py	Mon Aug 09 10:43:07 2010 -0600
+++ b/sage/graphs/generic_graph.py	Thu Aug 12 11:31:55 2010 +0800
@@ -2122,6 +2122,64 @@
             M[index,index]+=1
             return abs(M.determinant())   
 
+    def cycle_basis(self):
+        r"""
+        Returns a list of cycles which form a basis of the cycle space
+        of ``self``.
+
+        A basis of cycles of a graph is a minimal collection of cycles
+        (considered as sets of edges) such that the edge set of any
+        cycle in the graph can be written as a `Z/2Z` sum of the
+        cycles in the basis.
+
+        OUTPUT:
+
+        A list of lists, each of them representing the vertices of a
+        cycle in a basis.
+
+        ALGORITHM:
+
+        Uses the NetworkX library.
+
+        EXAMPLE:
+
+        A cycle basis in Petersen's Graph ::
+
+            sage: g = graphs.PetersenGraph()
+            sage: g.cycle_basis()
+            [[1, 2, 7, 5, 0], [8, 3, 2, 7, 5], [4, 3, 2, 7, 5, 0], [4, 9, 7, 5, 0], [8, 6, 9, 7, 5], [1, 6, 9, 7, 5, 0]]
+
+        Checking the given cycles are algebraically free::
+
+            sage: g = graphs.RandomGNP(30,.4)
+            sage: basis = g.cycle_basis()
+
+        Building the space of (directed) edges over `Z/2Z`. On the way,
+        building a dictionary associating an unique vector to each
+        undirected edge::
+            
+            sage: m = g.size()
+            sage: edge_space = VectorSpace(FiniteField(2),m)
+            sage: edge_vector = dict( zip( g.edges(labels = False), edge_space.basis() ) )
+            sage: for (u,v),vec in edge_vector.items():
+            ...      edge_vector[(v,u)] = vec
+
+        Defining a lambda function associating a vector to the
+        vertices of a cycle::
+
+            sage: vertices_to_edges = lambda x : zip( x, x[1:] + [x[0]] )
+            sage: cycle_to_vector = lambda x : sum( edge_vector[e] for e in vertices_to_edges(x) )
+
+        Finally checking the cycles are a free set::
+
+            sage: basis_as_vectors = map( cycle_to_vector, basis )
+            sage: edge_space.span(basis_as_vectors).rank() == len(basis)
+            True
+        """
+
+        import networkx
+        return networkx.cycle_basis(self.networkx_graph(copy=False))
+
     def minimum_outdegree_orientation(self, use_edge_labels=False, solver=None, verbose=0):
         r"""
         Returns a DiGraph which is an orientation with the smallest
@@ -2230,7 +2288,7 @@
 
         O.delete_edges(edges)
 
-        return O        
+        return O
 
     ### Planarity