| 2107 | def spanning_trees(self, root_vertex=0): |
| 2108 | """ |
| 2109 | Returns the number of spanning trees in a graph. In the case of a |
| 2110 | digraph, use vertex number of the desired root vertex as argument. |
| 2111 | Default is to set first vertex as root. |
| 2112 | |
| 2113 | This computation uses Kirchhoff's Matrix Tree Theorem [1] to calculate |
| 2114 | the number of spanning trees. For complete graphs on n vertices the |
| 2115 | result can also be reached using Cayley's formula: the number of |
| 2116 | spanning trees are n^(n-2). |
| 2117 | |
| 2118 | For digraphs, the augmented Kirchhoff Matrix as defined in [2] is |
| 2119 | used for calculations. Here the result is the number of out-trees |
| 2120 | rooted at a specific vertex. |
| 2121 | |
| 2122 | INPUT: |
| 2123 | |
| 2124 | - ``root_vertex`` - integer (default: 0, or the number of the first |
| 2125 | vertex if vertex 0 not is in the graph) This is the vertex that will be |
| 2126 | used as root for all spanning trees if the graph is a directed graph. |
| 2127 | |
| 2128 | REFERENCES: |
| 2129 | |
| 2130 | - [1] http://mathworld.wolfram.com/MatrixTreeTheorem.html |
| 2131 | |
| 2132 | - [2] Lih-Hsing Hsu, Cheng-Kuan Lin, "Graph Theory and Interconnection |
| 2133 | Networks" |
| 2134 | |
| 2135 | AUTHORS: |
| 2136 | |
| 2137 | - Anders Jonsson (2009-10-10) |
| 2138 | |
| 2139 | EXAMPLES:: |
| 2140 | |
| 2141 | sage: G = graphs.PetersenGraph() |
| 2142 | sage: G.spanning_trees() |
| 2143 | 2000 |
| 2144 | |
| 2145 | :: |
| 2146 | |
| 2147 | sage: n = 11 |
| 2148 | sage: G = graphs.CompleteGraph(n) |
| 2149 | sage: ST = G.spanning_trees() |
| 2150 | sage: ST == n^(n-2) |
| 2151 | True |
| 2152 | |
| 2153 | :: |
| 2154 | |
| 2155 | sage: M=matrix(3,3,[0,1,0,0,0,1,1,1,0]) |
| 2156 | sage: D=DiGraph(M) |
| 2157 | sage: D.spanning_trees() |
| 2158 | 1 |
| 2159 | sage: D.spanning_trees(0) |
| 2160 | 1 |
| 2161 | sage: D.spanning_trees(2) |
| 2162 | 2 |
| 2163 | |
| 2164 | """ |
| 2165 | if self.is_directed() == False: |
| 2166 | M=self.kirchhoff_matrix() |
| 2167 | M.subdivide(1,1) |
| 2168 | M2 = M.subdivision(1,1) |
| 2169 | return abs(M2.determinant()) |
| 2170 | else: |
| 2171 | G=self.copy() |
| 2172 | n = G.vertices()[G.order()-1] + 1 |
| 2173 | if root_vertex == 0: |
| 2174 | root_vertex=G.vertices()[0] |
| 2175 | if root_vertex not in G.vertices(): |
| 2176 | raise RuntimeError("Vertex (%s) not in the graph."%root_vertex) |
| 2177 | G.add_vertex(n) |
| 2178 | G.add_edge(n,root_vertex) |
| 2179 | M=G.kirchhoff_matrix() |
| 2180 | j=0 |
| 2181 | for i in G.vertices(): |
| 2182 | M[j,j]=G.in_degree(i) |
| 2183 | j= j + 1 |
| 2184 | M.subdivide(G.order()-1,G.order()-1) |
| 2185 | M2=M.subdivision(0,0) |
| 2186 | return abs(M2.determinant()) |
| 2187 | |