Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/graphs/base/static_dense_graph.pyx
8815 views
1
r"""
2
Static dense graphs
3
4
This module gathers everything which is related to static dense graphs, i.e. :
5
6
- The vertices are integer from `0` to `n-1`
7
- No labels on vertices/edges
8
- No multiple edges
9
- No addition/removal of vertices
10
11
This being said, it is technically possible to add/remove edges. The data
12
structure does not mind at all.
13
14
It is all based on the binary matrix data structure described in
15
``misc/binary_matrix.pxi``, which is almost a copy of the bitset data
16
structure. The only difference is that it differentiates the rows (the vertices)
17
instead of storing the whole data in a long bitset, and we can use that.
18
19
Index
20
-----
21
22
**Cython functions**
23
24
.. csv-table::
25
:class: contentstable
26
:widths: 30, 70
27
:delim: |
28
29
``dense_graph_init`` | Fills a binary matrix with the information of a (di)graph.
30
31
**Python functions**
32
33
.. csv-table::
34
:class: contentstable
35
:widths: 30, 70
36
:delim: |
37
38
:meth:`is_strongly_regular` | Tests if a graph is strongly regular
39
40
Functions
41
---------
42
"""
43
include "sage/misc/binary_matrix.pxi"
44
45
cdef dict dense_graph_init(binary_matrix_t m, g, translation = False):
46
r"""
47
Initializes the binary matrix from a Sage (di)graph.
48
49
INPUT:
50
51
- ``binary_matrix_t m`` -- the binary matrix to be filled
52
53
- ``g`` -- a graph or digraph
54
55
- ``translation`` (boolean) -- whether to return a dictionary associating to
56
each vertex its corresponding integer in the binary matrix.
57
"""
58
cdef dict d_translation
59
from sage.graphs.graph import Graph
60
cdef int is_undirected = isinstance(g, Graph)
61
cdef int n = g.order()
62
63
binary_matrix_init(m,n,n)
64
binary_matrix_fill(m,0)
65
66
# If the vertices are 0...n-1, let's avoid an unnecessary dictionary
67
if g.vertices() == range(n):
68
if translation:
69
d_translation = {i:i for i in range(n)}
70
71
for i,j in g.edge_iterator(labels = False):
72
binary_matrix_set1(m,i,j)
73
if is_undirected:
74
binary_matrix_set1(m,j,i)
75
else:
76
d_translation = {v:i for i,v in enumerate(g.vertices())}
77
78
for u,v in g.edge_iterator(labels = False):
79
binary_matrix_set1(m,d_translation[u],d_translation[v])
80
if is_undirected:
81
binary_matrix_set1(m,d_translation[v],d_translation[u])
82
83
if translation:
84
return d_translation
85
86
def is_strongly_regular(g, parameters = False):
87
r"""
88
Tests whether ``self`` is strongly regular.
89
90
A graph `G` is said to be strongly regular with parameters `(n, k, \lambda,
91
\mu)` if and only if:
92
93
* `G` has `n` vertices.
94
95
* `G` is `k`-regular.
96
97
* Any two adjacent vertices of `G` have `\lambda` common neighbors.
98
99
* Any two non-adjacent vertices of `G` have `\mu` common neighbors.
100
101
By convention, the complete graphs, the graphs with no edges
102
and the empty graph are not strongly regular.
103
104
See :wikipedia:`Strongly regular graph`
105
106
INPUT:
107
108
- ``parameters`` (boolean) -- whether to return the quadruple `(n,
109
k,\lambda,\mu)`. If ``parameters = False`` (default), this method only
110
returns ``True`` and ``False`` answers. If ``parameters=True``, the
111
``True`` answers are replaced by quadruples `(n, k,\lambda,\mu)`. See
112
definition above.
113
114
EXAMPLES:
115
116
Petersen's graph is strongly regular::
117
118
sage: g = graphs.PetersenGraph()
119
sage: g.is_strongly_regular()
120
True
121
sage: g.is_strongly_regular(parameters = True)
122
(10, 3, 0, 1)
123
124
And Clebsch's graph is too::
125
126
sage: g = graphs.ClebschGraph()
127
sage: g.is_strongly_regular()
128
True
129
sage: g.is_strongly_regular(parameters = True)
130
(16, 5, 0, 2)
131
132
But Chvatal's graph is not::
133
134
sage: g = graphs.ChvatalGraph()
135
sage: g.is_strongly_regular()
136
False
137
138
Complete graphs are not strongly regular. (:trac:`14297`) ::
139
140
sage: g = graphs.CompleteGraph(5)
141
sage: g.is_strongly_regular()
142
False
143
144
Completements of complete graphs are not strongly regular::
145
146
sage: g = graphs.CompleteGraph(5).complement()
147
sage: g.is_strongly_regular()
148
False
149
150
The empty graph is not strongly regular::
151
152
sage: g = graphs.EmptyGraph()
153
sage: g.is_strongly_regular()
154
False
155
"""
156
g._scream_if_not_simple(allow_loops=True)
157
cdef binary_matrix_t m
158
cdef int n = g.order()
159
cdef int inter
160
cdef int i,j,l, k
161
162
if g.size() == 0: # no vertices or no edges
163
return False
164
165
if g.is_clique():
166
return False
167
168
cdef list degree = g.degree()
169
k = degree[0]
170
if not all(d == k for d in degree):
171
return False
172
173
# m i now our copy of the graph
174
dense_graph_init(m, g)
175
176
cdef int llambda = -1
177
cdef int mu = -1
178
179
for i in range(n):
180
for j in range(i+1,n):
181
182
# The intersection of the common neighbors of i and j is a AND of
183
# their respective rows. A popcount then returns its cardinality.
184
inter = 0
185
for l in range(m.width):
186
inter += __builtin_popcountl(m.rows[i][l] & m.rows[j][l])
187
188
# Check that this cardinality is correct according to the values of lambda and mu
189
if binary_matrix_get(m,i,j):
190
if llambda == -1:
191
llambda = inter
192
elif llambda != inter:
193
binary_matrix_free(m)
194
return False
195
else:
196
if mu == -1:
197
mu = inter
198
elif mu != inter:
199
binary_matrix_free(m)
200
return False
201
202
binary_matrix_free(m)
203
204
if parameters:
205
return (n,k,llambda,mu)
206
else:
207
return True
208
209