| 430 | | - Brendan D. McKay, Isomorph-Free Exhaustive generation. Journal |
| 431 | | of Algorithms Volume 26, Issue 2, February 1998, pages 306-324. |
| 432 | | """ |
| 433 | | |
| 434 | | ################################################################################ |
| 435 | | # Basic Structures |
| 436 | | ################################################################################ |
| 437 | | |
| | 428 | - Brendan D. McKay, Isomorph-Free Exhaustive generation. *Journal |
| | 429 | of Algorithms*, Volume 26, Issue 2, February 1998, pages 306-324. |
| | 430 | """ |
| | 431 | |
| | 432 | ####################################################################### |
| | 433 | # Basic Structures |
| | 434 | ####################################################################### |
| | 435 | |
| 444 | | of order n2 connecting two complete graphs of order n1 each. |
| 445 | | |
| 446 | | This constructor depends on NetworkX numeric labels. In this case, |
| 447 | | the (n1)th node connects to the path graph from one complete graph |
| 448 | | and the (n1+n2+1)th node connects to the path graph from the other |
| 449 | | complete graph. |
| 450 | | |
| 451 | | PLOTTING: Upon construction, the position dictionary is filled to |
| | 442 | of order ``n2`` connecting two complete graphs of order ``n1`` each. |
| | 443 | |
| | 444 | This constructor depends on `NetworkX <http://networkx.lanl.gov>`_ |
| | 445 | numeric labels. In this case, the ``n1``-th node connects to the |
| | 446 | path graph from one complete graph and the ``n1 + n2 + 1``-th node |
| | 447 | connects to the path graph from the other complete graph. |
| | 448 | |
| | 449 | INPUT: |
| | 450 | |
| | 451 | - ``n1`` -- integer `\geq 2`. The order of each of the two |
| | 452 | complete graphs. |
| | 453 | |
| | 454 | - ``n2`` -- nonnegative integer. The order of the path graph |
| | 455 | connecting the two complete graphs. |
| | 456 | |
| | 457 | OUTPUT: |
| | 458 | |
| | 459 | A barbell graph of order ``2*n1 + n2``. A ``ValueError`` is |
| | 460 | returned if ``n1 < 2`` or ``n2 < 0``. |
| | 461 | |
| | 462 | ALGORITHM: |
| | 463 | |
| | 464 | Uses `NetworkX <http://networkx.lanl.gov>`_. |
| | 465 | |
| | 466 | PLOTTING: |
| | 467 | |
| | 468 | Upon construction, the position dictionary is filled to |
| 457 | | complete graph, and the (n1+n2+1)th node will be drawn 45 degrees |
| 458 | | below the left horizontal center of the second complete graph. |
| 459 | | |
| 460 | | EXAMPLES: Construct and show a barbell graph Bar = 4, Bells = 9 |
| 461 | | |
| 462 | | :: |
| 463 | | |
| 464 | | sage: g = graphs.BarbellGraph(9,4) |
| 465 | | sage: g.show() # long time |
| 466 | | |
| 467 | | Create several barbell graphs in a Sage graphics array |
| 468 | | |
| 469 | | :: |
| 470 | | |
| | 474 | complete graph, and the ``n1 + n2 + 1``-th node will be drawn 45 |
| | 475 | degrees below the left horizontal center of the second complete graph. |
| | 476 | |
| | 477 | EXAMPLES: |
| | 478 | |
| | 479 | Construct and show a barbell graph ``Bar = 4``, ``Bells = 9``:: |
| | 480 | |
| | 481 | sage: g = graphs.BarbellGraph(9, 4); g |
| | 482 | Barbell graph: Graph on 22 vertices |
| | 483 | sage: g.show() # long time |
| | 484 | |
| | 485 | An ``n1 >= 2``, ``n2 >= 0`` barbell graph has order ``2*n1 + n2``. It |
| | 486 | has the complete graph on ``n1`` vertices as a subgraph. It also has |
| | 487 | the path graph on ``n2`` vertices as a subgraph. :: |
| | 488 | |
| | 489 | sage: n1 = randint(2, 2*10^2) |
| | 490 | sage: n2 = randint(0, 2*10^2) |
| | 491 | sage: g = graphs.BarbellGraph(n1, n2) |
| | 492 | sage: v = 2*n1 + n2 |
| | 493 | sage: g.order() == v |
| | 494 | True |
| | 495 | sage: K_n1 = graphs.CompleteGraph(n1) |
| | 496 | sage: P_n2 = graphs.PathGraph(n2) |
| | 497 | sage: s_K = g.subgraph_search(K_n1, induced=True) |
| | 498 | sage: s_P = g.subgraph_search(P_n2, induced=True) |
| | 499 | sage: K_n1.is_isomorphic(s_K) |
| | 500 | True |
| | 501 | sage: P_n2.is_isomorphic(s_P) |
| | 502 | True |
| | 503 | |
| | 504 | Create several barbell graphs in a Sage graphics array:: |
| | 505 | |
| 478 | | ... n = [] |
| 479 | | ... for m in range(3): |
| 480 | | ... n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False)) |
| 481 | | ... j.append(n) |
| 482 | | ... |
| 483 | | sage: G = sage.plot.plot.GraphicsArray(j) |
| 484 | | sage: G.show() # long time |
| 485 | | """ |
| 486 | | pos_dict = {} |
| 487 | | |
| | 513 | ... n = [] |
| | 514 | ... for m in range(3): |
| | 515 | ... n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False)) |
| | 516 | ... j.append(n) |
| | 517 | ... |
| | 518 | sage: G = sage.plot.plot.GraphicsArray(j) |
| | 519 | sage: G.show() # long time |
| | 520 | |
| | 521 | TESTS: |
| | 522 | |
| | 523 | The input ``n1`` must be `\geq 2`:: |
| | 524 | |
| | 525 | sage: graphs.BarbellGraph(1, randint(0, 10^6)) |
| | 526 | Traceback (most recent call last): |
| | 527 | ... |
| | 528 | ValueError: Invalid graph description, n1 should be >= 2 |
| | 529 | sage: graphs.BarbellGraph(randint(-10^6, 1), randint(0, 10^6)) |
| | 530 | Traceback (most recent call last): |
| | 531 | ... |
| | 532 | ValueError: Invalid graph description, n1 should be >= 2 |
| | 533 | |
| | 534 | The input ``n2`` must be `\geq 0`:: |
| | 535 | |
| | 536 | sage: graphs.BarbellGraph(randint(2, 10^6), -1) |
| | 537 | Traceback (most recent call last): |
| | 538 | ... |
| | 539 | ValueError: Invalid graph description, n2 should be >= 0 |
| | 540 | sage: graphs.BarbellGraph(randint(2, 10^6), randint(-10^6, -1)) |
| | 541 | Traceback (most recent call last): |
| | 542 | ... |
| | 543 | ValueError: Invalid graph description, n2 should be >= 0 |
| | 544 | sage: graphs.BarbellGraph(randint(-10^6, 1), randint(-10^6, -1)) |
| | 545 | Traceback (most recent call last): |
| | 546 | ... |
| | 547 | ValueError: Invalid graph description, n1 should be >= 2 |
| | 548 | """ |
| | 549 | # sanity checks |
| | 550 | if n1 < 2: |
| | 551 | raise ValueError("Invalid graph description, n1 should be >= 2") |
| | 552 | if n2 < 0: |
| | 553 | raise ValueError("Invalid graph description, n2 should be >= 0") |
| | 554 | |
| | 555 | pos_dict = {} |
| | 556 | |
| 489 | | x = float(cos((pi/4) - ((2*pi)/n1)*i) - n2/2 - 1) |
| 490 | | y = float(sin((pi/4) - ((2*pi)/n1)*i) - n2/2 - 1) |
| 491 | | j = n1-1-i |
| 492 | | pos_dict[j] = (x,y) |
| 493 | | for i in range(n1,n1+n2): |
| 494 | | x = float(i - n1 - n2/2 + 1) |
| 495 | | y = float(i - n1 - n2/2 + 1) |
| 496 | | pos_dict[i] = (x,y) |
| 497 | | for i in range(n1+n2,2*n1+n2): |
| 498 | | x = float(cos((5*pi/4) + ((2*pi)/n1)*(i-n1-n2)) + n2/2 + 2) |
| 499 | | y = float(sin((5*pi/4) + ((2*pi)/n1)*(i-n1-n2)) + n2/2 + 2) |
| 500 | | pos_dict[i] = (x,y) |
| 501 | | |
| 502 | | import networkx |
| 503 | | G = networkx.barbell_graph(n1,n2) |
| | 558 | x = float(cos((pi / 4) - ((2 * pi) / n1) * i) - (n2 / 2) - 1) |
| | 559 | y = float(sin((pi / 4) - ((2 * pi) / n1) * i) - (n2 / 2) - 1) |
| | 560 | j = n1 - 1 - i |
| | 561 | pos_dict[j] = (x, y) |
| | 562 | for i in range(n1, n1 + n2): |
| | 563 | x = float(i - n1 - (n2 / 2) + 1) |
| | 564 | y = float(i - n1 - (n2 / 2) + 1) |
| | 565 | pos_dict[i] = (x, y) |
| | 566 | for i in range(n1 + n2, (2 * n1) + n2): |
| | 567 | x = float( |
| | 568 | cos((5 * (pi / 4)) + ((2 * pi) / n1) * (i - n1 - n2)) |
| | 569 | + (n2 / 2) + 2) |
| | 570 | y = float( |
| | 571 | sin((5 * (pi / 4)) + ((2 * pi) / n1) * (i - n1 - n2)) |
| | 572 | + (n2 / 2) + 2) |
| | 573 | pos_dict[i] = (x, y) |
| | 574 | |
| | 575 | import networkx |
| | 576 | G = networkx.barbell_graph(n1, n2) |
| 520 | | |
| 521 | | EXAMPLES: Construct and show a bull graph |
| 522 | | |
| 523 | | :: |
| 524 | | |
| 525 | | sage: g = graphs.BullGraph() |
| 526 | | sage: g.show() # long time |
| 527 | | """ |
| 528 | | pos_dict = {0:(0,0),1:(-1,1),2:(1,1),3:(-2,2),4:(2,2)} |
| | 596 | |
| | 597 | ALGORITHM: |
| | 598 | |
| | 599 | Uses `NetworkX <http://networkx.lanl.gov>`_. |
| | 600 | |
| | 601 | EXAMPLES: |
| | 602 | |
| | 603 | Construct and show a bull graph:: |
| | 604 | |
| | 605 | sage: g = graphs.BullGraph(); g |
| | 606 | Bull graph: Graph on 5 vertices |
| | 607 | sage: g.show() # long time |
| | 608 | |
| | 609 | The bull graph has 5 vertices and 5 edges. Its radius is 2, its |
| | 610 | diameter 3, and its girth 3. The bull graph is planar with chromatic |
| | 611 | number 3 and chromatic index also 3. :: |
| | 612 | |
| | 613 | sage: g.order(); g.size() |
| | 614 | 5 |
| | 615 | 5 |
| | 616 | sage: g.radius(); g.diameter(); g.girth() |
| | 617 | 2 |
| | 618 | 3 |
| | 619 | 3 |
| | 620 | sage: g.chromatic_number() |
| | 621 | 3 |
| | 622 | |
| | 623 | The bull graph has chromatic polynomial `x(x - 2)(x - 1)^3` and |
| | 624 | Tutte polynomial `x^4 + x^3 + x^2 y`. Its characteristic polynomial |
| | 625 | is `x(x^2 - x - 3)(x^2 + x - 1)`, which follows from the definition of |
| | 626 | characteristic polynomials for graphs, i.e. `\det(xI - A)`, where |
| | 627 | `x` is a variable, `A` the adjacency matrix of the graph, and `I` |
| | 628 | the identity matrix of the same dimensions as `A`. :: |
| | 629 | |
| | 630 | sage: chrompoly = g.chromatic_polynomial() |
| | 631 | sage: bool(expand(x * (x - 2) * (x - 1)^3) == chrompoly) |
| | 632 | True |
| | 633 | sage: charpoly = g.characteristic_polynomial() |
| | 634 | sage: M = g.adjacency_matrix(); M |
| | 635 | [0 1 1 0 0] |
| | 636 | [1 0 1 1 0] |
| | 637 | [1 1 0 0 1] |
| | 638 | [0 1 0 0 0] |
| | 639 | [0 0 1 0 0] |
| | 640 | sage: Id = identity_matrix(ZZ, M.nrows()) |
| | 641 | sage: D = x*Id - M |
| | 642 | sage: bool(D.determinant() == charpoly) |
| | 643 | True |
| | 644 | sage: bool(expand(x * (x^2 - x - 3) * (x^2 + x - 1)) == charpoly) |
| | 645 | True |
| | 646 | """ |
| | 647 | pos_dict = {0:(0,0), 1:(-1,1), 2:(1,1), 3:(-2,2), 4:(2,2)} |
| 1830 | | |
| 1831 | | The Chvatal graph has 12 vertices. It is a 4-regular, 4-chromatic |
| 1832 | | graph. It is one of the few known graphs to satisfy Grunbaum's |
| 1833 | | conjecture that for every m 1, n 2, there is an m-regular, |
| 1834 | | m-chromatic graph of girth at least n. |
| 1835 | | |
| 1836 | | EXAMPLE:: |
| 1837 | | |
| 1838 | | sage: G = graphs.ChvatalGraph() |
| | 1948 | |
| | 1949 | Chvatal graph is one of the few known graphs to satisfy Grunbaum's |
| | 1950 | conjecture that for every m, n, there is an m-regular, |
| | 1951 | m-chromatic graph of girth at least n. For more information, see this |
| | 1952 | `Wikipedia article on the Chvatal graph <http://en.wikipedia.org/wiki/Chv%C3%A1tal_graph>`_. |
| | 1953 | |
| | 1954 | EXAMPLES: |
| | 1955 | |
| | 1956 | The Chvatal graph has 12 vertices and 24 edges. It is a 4-regular, |
| | 1957 | 4-chromatic graph with radius 2, diameter 2, and girth 4. :: |
| | 1958 | |
| | 1959 | sage: G = graphs.ChvatalGraph(); G |
| | 1960 | Chvatal graph: Graph on 12 vertices |
| | 1961 | sage: G.order(); G.size() |
| | 1962 | 12 |
| | 1963 | 24 |
| 3204 | | n symbols. Two vertices are adjacent if one can be obtained from the |
| 3205 | | other by swapping the labels in the ith and (i+1)th position for |
| 3206 | | `1 \leq i \leq n-1`. |
| 3207 | | |
| 3208 | | INPUT: |
| 3209 | | |
| 3210 | | - ``n`` |
| 3211 | | |
| 3212 | | EXAMPLES:: |
| 3213 | | |
| 3214 | | sage: g = graphs.BubbleSortGraph(4) |
| | 3335 | `n` symbols. Two vertices are adjacent if one can be obtained from the |
| | 3336 | other by swapping the labels in the `i`-th and `(i+1)`-th positions for |
| | 3337 | `1 \leq i \leq n-1`. In total, `B(n)` has order `n!`. Thus, the order |
| | 3338 | of `B(n)` increases according to `f(n) = n!`. |
| | 3339 | |
| | 3340 | INPUT: |
| | 3341 | |
| | 3342 | - ``n`` -- positive integer. The number of symbols to permute. |
| | 3343 | |
| | 3344 | OUTPUT: |
| | 3345 | |
| | 3346 | The bubble sort graph `B(n)` on `n` symbols. If `n < 1`, a |
| | 3347 | ``ValueError`` is returned. |
| | 3348 | |
| | 3349 | EXAMPLES:: |
| | 3350 | |
| | 3351 | sage: g = graphs.BubbleSortGraph(4); g |
| | 3352 | Bubble sort: Graph on 24 vertices |
| 3216 | | |
| 3217 | | AUTHORS: |
| 3218 | | |
| | 3354 | |
| | 3355 | The bubble sort graph on `n = 1` symbol is the trivial graph `K_1`:: |
| | 3356 | |
| | 3357 | sage: graphs.BubbleSortGraph(1) |
| | 3358 | Bubble sort: Graph on 1 vertex |
| | 3359 | |
| | 3360 | If `n \geq 1`, then the order of `B(n)` is `n!`:: |
| | 3361 | |
| | 3362 | sage: n = randint(1, 8) |
| | 3363 | sage: g = graphs.BubbleSortGraph(n) |
| | 3364 | sage: g.order() == factorial(n) |
| | 3365 | True |
| | 3366 | |
| | 3367 | TESTS: |
| | 3368 | |
| | 3369 | Input ``n`` must be positive:: |
| | 3370 | |
| | 3371 | sage: graphs.BubbleSortGraph(0) |
| | 3372 | Traceback (most recent call last): |
| | 3373 | ... |
| | 3374 | ValueError: Invalid number of symbols to permute, n should be >= 1 |
| | 3375 | sage: graphs.BubbleSortGraph(randint(-10^6, 0)) |
| | 3376 | Traceback (most recent call last): |
| | 3377 | ... |
| | 3378 | ValueError: Invalid number of symbols to permute, n should be >= 1 |
| | 3379 | |
| | 3380 | AUTHORS: |
| | 3381 | |
| 3251 | | |
| 3252 | | EXAMPLE: Plot a balanced tree of height 4 with r = 3 |
| 3253 | | |
| 3254 | | :: |
| 3255 | | |
| | 3419 | |
| | 3420 | INPUT: |
| | 3421 | |
| | 3422 | - ``r`` -- positive integer `\geq 2`. The degree of the root node. |
| | 3423 | |
| | 3424 | - ``h`` -- positive integer `\geq 1`. The height of the balanced tree. |
| | 3425 | |
| | 3426 | OUTPUT: |
| | 3427 | |
| | 3428 | The perfectly balanced tree of height `h \geq 1` and whose root has |
| | 3429 | degree `r \geq 2`. A ``NetworkXError`` is returned if `r < 2` or |
| | 3430 | `h < 1`. |
| | 3431 | |
| | 3432 | ALGORITHM: |
| | 3433 | |
| | 3434 | Uses `NetworkX <http://networkx.lanl.gov>`_. |
| | 3435 | |
| | 3436 | EXAMPLES: |
| | 3437 | |
| | 3438 | A balanced tree whose root node has degree `r = 2`, and of height |
| | 3439 | `h = 1`, has order 3 and size 2:: |
| | 3440 | |
| | 3441 | sage: G = graphs.BalancedTree(2, 1); G |
| | 3442 | Balanced tree: Graph on 3 vertices |
| | 3443 | sage: G.order(); G.size() |
| | 3444 | 3 |
| | 3445 | 2 |
| | 3446 | sage: r = 2; h = 1 |
| | 3447 | sage: v = 1 + r |
| | 3448 | sage: v; v - 1 |
| | 3449 | 3 |
| | 3450 | 2 |
| | 3451 | |
| | 3452 | Plot a balanced tree of height 5, whose root node has degree `r = 3`:: |
| | 3453 | |
| 3258 | | """ |
| 3259 | | import networkx |
| 3260 | | return graph.Graph(networkx.balanced_tree(r, h), name="Balanced Tree") |
| | 3456 | |
| | 3457 | A tree is bipartite. If its vertex set is finite, then it is planar. :: |
| | 3458 | |
| | 3459 | sage: r = randint(2, 5); h = randint(1, 7) |
| | 3460 | sage: T = graphs.BalancedTree(r, h) |
| | 3461 | sage: T.is_bipartite() |
| | 3462 | True |
| | 3463 | sage: T.is_planar() |
| | 3464 | True |
| | 3465 | sage: v = (r^(h + 1) - 1) / (r - 1) |
| | 3466 | sage: T.order() == v |
| | 3467 | True |
| | 3468 | sage: T.size() == v - 1 |
| | 3469 | True |
| | 3470 | |
| | 3471 | TESTS: |
| | 3472 | |
| | 3473 | We only consider balanced trees whose root node has degree `r \geq 2`:: |
| | 3474 | |
| | 3475 | sage: graphs.BalancedTree(1, randint(1, 10^6)) |
| | 3476 | Traceback (most recent call last): |
| | 3477 | ... |
| | 3478 | NetworkXError: Invalid graph description, r should be >=2 |
| | 3479 | sage: graphs.BalancedTree(randint(-10^6, 1), randint(1, 10^6)) |
| | 3480 | Traceback (most recent call last): |
| | 3481 | ... |
| | 3482 | NetworkXError: Invalid graph description, r should be >=2 |
| | 3483 | |
| | 3484 | The tree must have height `h \geq 1`:: |
| | 3485 | |
| | 3486 | sage: graphs.BalancedTree(randint(2, 10^6), 0) |
| | 3487 | Traceback (most recent call last): |
| | 3488 | ... |
| | 3489 | NetworkXError: Invalid graph description, h should be >=1 |
| | 3490 | sage: graphs.BalancedTree(randint(2, 10^6), randint(-10^6, 0)) |
| | 3491 | Traceback (most recent call last): |
| | 3492 | ... |
| | 3493 | NetworkXError: Invalid graph description, h should be >=1 |
| | 3494 | sage: graphs.BalancedTree(randint(-10^6, 1), randint(-10^6, 0)) |
| | 3495 | Traceback (most recent call last): |
| | 3496 | ... |
| | 3497 | NetworkXError: Invalid graph description, r should be >=2 |
| | 3498 | """ |
| | 3499 | import networkx |
| | 3500 | return graph.Graph(networkx.balanced_tree(r, h), name="Balanced tree") |