| 269 | def WellsGraph(): |
| 270 | r""" |
| 271 | Returns the Wells graph. |
| 272 | |
| 273 | For more information on the Wells graph (also called Armanios-Wells graph), |
| 274 | see `this page <http://www.win.tue.nl/~aeb/graphs/Wells.html>`_. |
| 275 | |
| 276 | The implementation follows the construction given on page 266 of |
| 277 | [BCN89]_. This requires to create intermediate graphs and run a small |
| 278 | isomorphism test, while everything could be replaced by a pre-computed list |
| 279 | of edges : I believe that it is better to keep "the recipe" in the code, |
| 280 | however, as it is quite unlikely that this could become the most |
| 281 | time-consuming operation in any sensible algorithm, and .... "preserves |
| 282 | knowledge", which is what open-source software is meant to do. |
| 283 | |
| 284 | EXAMPLES:: |
| 285 | |
| 286 | sage: g = graphs.WellsGraph(); g |
| 287 | Wells graph: Graph on 32 vertices |
| 288 | sage: g.order() |
| 289 | 32 |
| 290 | sage: g.size() |
| 291 | 80 |
| 292 | sage: g.girth() |
| 293 | 5 |
| 294 | sage: g.diameter() |
| 295 | 4 |
| 296 | sage: g.chromatic_number() |
| 297 | 4 |
| 298 | sage: g.is_regular(k=5) |
| 299 | True |
| 300 | |
| 301 | REFERENCES: |
| 302 | |
| 303 | .. [BCN89] A. E. Brouwer, A. M. Cohen, A. Neumaier, |
| 304 | Distance-Regular Graphs, |
| 305 | Springer, 1989. |
| 306 | """ |
| 307 | from platonic_solids import DodecahedralGraph |
| 308 | from basic import CompleteBipartiteGraph |
| 309 | |
| 310 | # Following the construction from the book "Distance-regular graphs" |
| 311 | dodecahedron = DodecahedralGraph() |
| 312 | |
| 313 | # Vertices at distance 3 in the Dodecahedron |
| 314 | distance3 = dodecahedron.distance_graph([3]) |
| 315 | |
| 316 | # Building the graph whose line graph is the dodecahedron. |
| 317 | b = CompleteBipartiteGraph(5,5) |
| 318 | b.delete_edges([(0,5), (1,6), (2,7), (3,8), (4,9)]) |
| 319 | |
| 320 | # Computing the isomorphism between the two |
| 321 | b = b.line_graph(labels = False) |
| 322 | _, labels = distance3.is_isomorphic(b, certify = True) |
| 323 | |
| 324 | # The relabeling that the books claims to exist. |
| 325 | for v,new_name in labels.items(): |
| 326 | x,y = new_name |
| 327 | labels[v] = (x%5,y%5) |
| 328 | |
| 329 | dodecahedron.relabel(labels) |
| 330 | |
| 331 | # Checking that the above computations indeed produces a good labeling. |
| 332 | for u in dodecahedron: |
| 333 | for v in dodecahedron: |
| 334 | if u == v: |
| 335 | continue |
| 336 | |
| 337 | if (u[0] != v[0]) and (u[1] != v[1]): |
| 338 | continue |
| 339 | |
| 340 | if dodecahedron.distance(u,v) != 3: |
| 341 | raise ValueError("There is something wrong going on !") |
| 342 | |
| 343 | # The graph we will return, starting from the dodecahedron |
| 344 | g = dodecahedron |
| 345 | |
| 346 | # Good ! Now adding 12 new vertices |
| 347 | for i in range(5): |
| 348 | g.add_edge((i,'+'),('inf','+')) |
| 349 | g.add_edge((i,'-'),('inf','-')) |
| 350 | for k in range(5): |
| 351 | if k == i: |
| 352 | continue |
| 353 | g.add_edge((i,'+'),(i,k)) |
| 354 | g.add_edge((i,'-'),(k,i)) |
| 355 | |
| 356 | g.name("Wells graph") |
| 357 | |
| 358 | # Giving our graph a "not-so-bad" layout |
| 359 | g.relabel({ |
| 360 | (1, 3): 8, (3, 0): 18, (3, '+'): 22, (2, 1): 13, |
| 361 | (1, '+'): 10, (0, 3): 2, (2, '+'): 16, ('inf', '-'): 31, |
| 362 | (4, 0): 24, (1, 2): 7, (4, '+'): 28, (0, '-'): 5, |
| 363 | (0, 4): 3, (4, 1): 25, (2, '-'): 17, (3, 2): 20, |
| 364 | (3, '-'): 23, (1, '-'): 11, (1, 4): 9, (2, 3): 14, |
| 365 | ('inf', '+'): 30, (4, 2): 26, (1, 0): 6, (0, 1): 0, |
| 366 | (3, 1): 19, (0, 2): 1, (2, 0): 12, (4, '-'): 29, |
| 367 | (0, '+'): 4, (4, 3): 27, (3, 4): 21, (2, 4): 15}) |
| 368 | |
| 369 | p = [(1, 29, 20, 13, 12, 28, 14, 7), |
| 370 | (2, 5, 30, 23, 18, 4, 31, 22), |
| 371 | (3, 17, 21, 9, 24, 16, 27, 25), |
| 372 | (6, 10, 8, 15, 0, 11, 19, 26)] |
| 373 | |
| 374 | from sage.graphs.graph_plot import _circle_embedding |
| 375 | _circle_embedding(g, p[0], radius = 1) |
| 376 | _circle_embedding(g, p[1], radius = .9) |
| 377 | _circle_embedding(g, p[2], radius = .8) |
| 378 | _circle_embedding(g, p[3], radius = .7) |
| 379 | |
| 380 | return g |
| 381 | |
| 382 | |