Ticket #13862: trac_13862-moves_3_constructors.patch
File trac_13862-moves_3_constructors.patch, 42.5 KB (added by , 8 years ago) |
---|
-
sage/graphs/generators/basic.py
# HG changeset patch # User Nathann Cohen <nathann.cohen@gmail.com> # Date 1356523694 -3600 # Node ID f728da1da8710218bc6ad6de05318d28ddac4e97 # Parent 3c8e3c18d3f23f9b05159f3aa10a01262468feb7 Split graph_generators into several files -- Moves 3 methods from families to basic diff --git a/sage/graphs/generators/basic.py b/sage/graphs/generators/basic.py
a b 186 186 sage: g.is_planar() 187 187 True 188 188 189 The Bucky Ball can also be created by extracting the 1-skeleton 189 The Bucky Ball can also be created by extracting the 1-skeleton 190 190 of the Bucky Ball polyhedron, but this is much slower. :: 191 191 192 192 sage: g = polytopes.buckyball().vertex_graph() … … 200 200 sage: g = graphs.BuckyBall() 201 201 sage: g.plot(vertex_labels=False, vertex_size=10).show() # long time 202 202 """ 203 edges = [(0, 2), (0, 48), (0, 59), (1, 3), (1, 9), (1, 58), 204 (2, 3), (2, 36), (3, 17), (4, 6), (4, 8), (4, 12), 205 (5, 7), (5, 9), (5, 16), (6, 7), (6, 20), (7, 21), 206 (8, 9), (8, 56), (10, 11), (10, 12), (10, 20), (11, 27), 207 (11, 47), (12, 13), (13, 46), (13, 54), (14, 15), (14, 16), 208 (14, 21), (15, 25), (15, 41), (16, 17), (17, 40), (18, 19), 209 (18, 20), (18, 26), (19, 21), (19, 24), (22, 23), (22, 31), 210 (22, 34), (23, 25), (23, 38), (24, 25), (24, 30), (26, 27), 211 (26, 30), (27, 29), (28, 29), (28, 31), (28, 35), (29, 44), 212 (30, 31), (32, 34), (32, 39), (32, 50), (33, 35), (33, 45), 213 (33, 51), (34, 35), (36, 37), (36, 40), (37, 39), (37, 52), 214 (38, 39), (38, 41), (40, 41), (42, 43), (42, 46), (42, 55), 215 (43, 45), (43, 53), (44, 45), (44, 47), (46, 47), (48, 49), 216 (48, 52), (49, 53), (49, 57), (50, 51), (50, 52), (51, 53), 203 edges = [(0, 2), (0, 48), (0, 59), (1, 3), (1, 9), (1, 58), 204 (2, 3), (2, 36), (3, 17), (4, 6), (4, 8), (4, 12), 205 (5, 7), (5, 9), (5, 16), (6, 7), (6, 20), (7, 21), 206 (8, 9), (8, 56), (10, 11), (10, 12), (10, 20), (11, 27), 207 (11, 47), (12, 13), (13, 46), (13, 54), (14, 15), (14, 16), 208 (14, 21), (15, 25), (15, 41), (16, 17), (17, 40), (18, 19), 209 (18, 20), (18, 26), (19, 21), (19, 24), (22, 23), (22, 31), 210 (22, 34), (23, 25), (23, 38), (24, 25), (24, 30), (26, 27), 211 (26, 30), (27, 29), (28, 29), (28, 31), (28, 35), (29, 44), 212 (30, 31), (32, 34), (32, 39), (32, 50), (33, 35), (33, 45), 213 (33, 51), (34, 35), (36, 37), (36, 40), (37, 39), (37, 52), 214 (38, 39), (38, 41), (40, 41), (42, 43), (42, 46), (42, 55), 215 (43, 45), (43, 53), (44, 45), (44, 47), (46, 47), (48, 49), 216 (48, 52), (49, 53), (49, 57), (50, 51), (50, 52), (51, 53), 217 217 (54, 55), (54, 56), (55, 57), (56, 58), (57, 59), (58, 59) 218 218 ] 219 219 g = graph.Graph() … … 436 436 drawn at the top of the inner-circle, moving clockwise after that. 437 437 The outer circle is drawn with the (n+1)th node at the top, then 438 438 counterclockwise as well. 439 439 440 440 EXAMPLES: Construct and show a circular ladder graph with 26 nodes 441 441 442 442 :: 443 443 444 444 sage: g = graphs.CircularLadderGraph(13) 445 445 sage: g.show() # long time 446 446 447 447 Create several circular ladder graphs in a Sage graphics array 448 448 449 449 :: 450 450 451 451 sage: g = [] 452 452 sage: j = [] 453 453 sage: for i in range(9): … … 475 475 import networkx 476 476 G = networkx.circular_ladder_graph(n) 477 477 return graph.Graph(G, pos=pos_dict, name="Circular Ladder graph") 478 478 479 479 def ClawGraph(): 480 480 """ 481 481 Returns a claw graph. 482 482 483 483 A claw graph is named for its shape. It is actually a complete 484 484 bipartite graph with (n1, n2) = (1, 3). 485 485 486 486 PLOTTING: See CompleteBipartiteGraph. 487 487 488 488 EXAMPLES: Show a Claw graph 489 489 490 490 :: 491 491 492 492 sage: (graphs.ClawGraph()).show() # long time 493 493 494 494 Inspect a Claw graph 495 495 496 496 :: 497 497 498 498 sage: G = graphs.ClawGraph() 499 499 sage: G 500 500 Claw graph: Graph on 4 vertices … … 507 507 def CycleGraph(n): 508 508 r""" 509 509 Returns a cycle graph with n nodes. 510 510 511 511 A cycle graph is a basic structure which is also typically called 512 512 an n-gon. 513 513 514 514 This constructor is dependent on vertices numbered 0 through n-1 in 515 515 NetworkX ``cycle_graph()`` 516 516 517 517 PLOTTING: Upon construction, the position dictionary is filled to 518 518 override the spring-layout algorithm. By convention, each cycle 519 519 graph will be displayed with the first (0) node at the top, with 520 520 the rest following in a counterclockwise manner. 521 521 522 522 The cycle graph is a good opportunity to compare efficiency of 523 523 filling a position dictionary vs. using the spring-layout algorithm 524 524 for plotting. Because the cycle graph is very symmetric, the 525 525 resulting plots should be similar (in cases of small n). 526 526 527 527 Filling the position dictionary in advance adds O(n) to the 528 528 constructor. 529 529 530 530 EXAMPLES: Compare plotting using the predefined layout and 531 531 networkx:: 532 533 sage: import networkx 532 533 sage: import networkx 534 534 sage: n = networkx.cycle_graph(23) 535 535 sage: spring23 = Graph(n) 536 536 sage: posdict23 = graphs.CycleGraph(23) 537 537 sage: spring23.show() # long time 538 538 sage: posdict23.show() # long time 539 539 540 540 We next view many cycle graphs as a Sage graphics array. First we 541 541 use the ``CycleGraph`` constructor, which fills in the 542 542 position dictionary:: 543 543 544 544 sage: g = [] 545 545 sage: j = [] 546 546 sage: for i in range(9): … … 555 555 ... 556 556 sage: G = sage.plot.graphics.GraphicsArray(j) 557 557 sage: G.show() # long time 558 558 559 559 Compare to plotting with the spring-layout algorithm:: 560 560 561 561 sage: g = [] 562 562 sage: j = [] 563 563 sage: for i in range(9): 564 ... spr = networkx.cycle_graph(i+3) 564 ... spr = networkx.cycle_graph(i+3) 565 565 ... k = Graph(spr) 566 566 ... g.append(k) 567 567 ... … … 579 579 x = float(cos((pi/2) + ((2*pi)/n)*i)) 580 580 y = float(sin((pi/2) + ((2*pi)/n)*i)) 581 581 pos_dict[i] = (x,y) 582 import networkx 582 import networkx 583 583 G = networkx.cycle_graph(n) 584 584 return graph.Graph(G, pos=pos_dict, name="Cycle graph") 585 585 586 def CompleteGraph(n): 587 """ 588 Returns a complete graph on n nodes. 589 590 A Complete Graph is a graph in which all nodes are connected to all 591 other nodes. 592 593 This constructor is dependent on vertices numbered 0 through n-1 in 594 NetworkX complete_graph() 595 596 PLOTTING: Upon construction, the position dictionary is filled to 597 override the spring-layout algorithm. By convention, each complete 598 graph will be displayed with the first (0) node at the top, with 599 the rest following in a counterclockwise manner. 600 601 In the complete graph, there is a big difference visually in using 602 the spring-layout algorithm vs. the position dictionary used in 603 this constructor. The position dictionary flattens the graph, 604 making it clear which nodes an edge is connected to. But the 605 complete graph offers a good example of how the spring-layout 606 works. The edges push outward (everything is connected), causing 607 the graph to appear as a 3-dimensional pointy ball. (See examples 608 below). 609 610 EXAMPLES: We view many Complete graphs with a Sage Graphics Array, 611 first with this constructor (i.e., the position dictionary 612 filled):: 613 614 sage: g = [] 615 sage: j = [] 616 sage: for i in range(9): 617 ... k = graphs.CompleteGraph(i+3) 618 ... g.append(k) 619 ... 620 sage: for i in range(3): 621 ... n = [] 622 ... for m in range(3): 623 ... n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False)) 624 ... j.append(n) 625 ... 626 sage: G = sage.plot.graphics.GraphicsArray(j) 627 sage: G.show() # long time 628 629 We compare to plotting with the spring-layout algorithm:: 630 631 sage: import networkx 632 sage: g = [] 633 sage: j = [] 634 sage: for i in range(9): 635 ... spr = networkx.complete_graph(i+3) 636 ... k = Graph(spr) 637 ... g.append(k) 638 ... 639 sage: for i in range(3): 640 ... n = [] 641 ... for m in range(3): 642 ... n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False)) 643 ... j.append(n) 644 ... 645 sage: G = sage.plot.graphics.GraphicsArray(j) 646 sage: G.show() # long time 647 648 Compare the constructors (results will vary) 649 650 :: 651 652 sage: import networkx 653 sage: t = cputime() 654 sage: n = networkx.complete_graph(389); spring389 = Graph(n) 655 sage: cputime(t) # random 656 0.59203700000000126 657 sage: t = cputime() 658 sage: posdict389 = graphs.CompleteGraph(389) 659 sage: cputime(t) # random 660 0.6680419999999998 661 662 We compare plotting:: 663 664 sage: import networkx 665 sage: n = networkx.complete_graph(23) 666 sage: spring23 = Graph(n) 667 sage: posdict23 = graphs.CompleteGraph(23) 668 sage: spring23.show() # long time 669 sage: posdict23.show() # long time 670 """ 671 pos_dict = {} 672 for i in range(n): 673 x = float(cos((pi/2) + ((2*pi)/n)*i)) 674 y = float(sin((pi/2) + ((2*pi)/n)*i)) 675 pos_dict[i] = (x,y) 676 import networkx 677 G = networkx.complete_graph(n) 678 return graph.Graph(G, pos=pos_dict, name="Complete graph") 679 680 def CompleteBipartiteGraph(n1, n2): 681 """ 682 Returns a Complete Bipartite Graph sized n1+n2, with each of the 683 nodes [0,(n1-1)] connected to each of the nodes [n1,(n2-1)] and 684 vice versa. 685 686 A Complete Bipartite Graph is a graph with its vertices partitioned 687 into two groups, V1 and V2. Each v in V1 is connected to every v in 688 V2, and vice versa. 689 690 PLOTTING: Upon construction, the position dictionary is filled to 691 override the spring-layout algorithm. By convention, each complete 692 bipartite graph will be displayed with the first n1 nodes on the 693 top row (at y=1) from left to right. The remaining n2 nodes appear 694 at y=0, also from left to right. The shorter row (partition with 695 fewer nodes) is stretched to the same length as the longer row, 696 unless the shorter row has 1 node; in which case it is centered. 697 The x values in the plot are in domain [0,maxn1,n2]. 698 699 In the Complete Bipartite graph, there is a visual difference in 700 using the spring-layout algorithm vs. the position dictionary used 701 in this constructor. The position dictionary flattens the graph and 702 separates the partitioned nodes, making it clear which nodes an 703 edge is connected to. The Complete Bipartite graph plotted with the 704 spring-layout algorithm tends to center the nodes in n1 (see 705 spring_med in examples below), thus overlapping its nodes and 706 edges, making it typically hard to decipher. 707 708 Filling the position dictionary in advance adds O(n) to the 709 constructor. Feel free to race the constructors below in the 710 examples section. The much larger difference is the time added by 711 the spring-layout algorithm when plotting. (Also shown in the 712 example below). The spring model is typically described as 713 `O(n^3)`, as appears to be the case in the NetworkX source 714 code. 715 716 EXAMPLES: Two ways of constructing the complete bipartite graph, 717 using different layout algorithms:: 718 719 sage: import networkx 720 sage: n = networkx.complete_bipartite_graph(389,157); spring_big = Graph(n) # long time 721 sage: posdict_big = graphs.CompleteBipartiteGraph(389,157) # long time 722 723 Compare the plotting:: 724 725 sage: n = networkx.complete_bipartite_graph(11,17) 726 sage: spring_med = Graph(n) 727 sage: posdict_med = graphs.CompleteBipartiteGraph(11,17) 728 729 Notice here how the spring-layout tends to center the nodes of n1 730 731 :: 732 733 sage: spring_med.show() # long time 734 sage: posdict_med.show() # long time 735 736 View many complete bipartite graphs with a Sage Graphics Array, 737 with this constructor (i.e., the position dictionary filled):: 738 739 sage: g = [] 740 sage: j = [] 741 sage: for i in range(9): 742 ... k = graphs.CompleteBipartiteGraph(i+1,4) 743 ... g.append(k) 744 ... 745 sage: for i in range(3): 746 ... n = [] 747 ... for m in range(3): 748 ... n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False)) 749 ... j.append(n) 750 ... 751 sage: G = sage.plot.graphics.GraphicsArray(j) 752 sage: G.show() # long time 753 754 We compare to plotting with the spring-layout algorithm:: 755 756 sage: g = [] 757 sage: j = [] 758 sage: for i in range(9): 759 ... spr = networkx.complete_bipartite_graph(i+1,4) 760 ... k = Graph(spr) 761 ... g.append(k) 762 ... 763 sage: for i in range(3): 764 ... n = [] 765 ... for m in range(3): 766 ... n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False)) 767 ... j.append(n) 768 ... 769 sage: G = sage.plot.graphics.GraphicsArray(j) 770 sage: G.show() # long time 771 772 Trac ticket #12155:: 773 774 sage: graphs.CompleteBipartiteGraph(5,6).complement() 775 complement(Complete bipartite graph): Graph on 11 vertices 776 """ 777 pos_dict = {} 778 c1 = 1 # scaling factor for top row 779 c2 = 1 # scaling factor for bottom row 780 c3 = 0 # pad to center if top row has 1 node 781 c4 = 0 # pad to center if bottom row has 1 node 782 if n1 > n2: 783 if n2 == 1: 784 c4 = (n1-1)/2 785 else: 786 c2 = ((n1-1)/(n2-1)) 787 elif n2 > n1: 788 if n1 == 1: 789 c3 = (n2-1)/2 790 else: 791 c1 = ((n2-1)/(n1-1)) 792 for i in range(n1): 793 x = c1*i + c3 794 y = 1 795 pos_dict[i] = (x,y) 796 for i in range(n1+n2)[n1:]: 797 x = c2*(i-n1) + c4 798 y = 0 799 pos_dict[i] = (x,y) 800 import networkx 801 from sage.graphs.graph import Graph 802 G = networkx.complete_bipartite_graph(n1,n2) 803 return Graph(G, pos=pos_dict, name="Complete bipartite graph") 804 805 def CompleteMultipartiteGraph(l): 806 r""" 807 Returns a complete multipartite graph. 808 809 INPUT: 810 811 - ``l`` -- a list of integers : the respective sizes 812 of the components. 813 814 EXAMPLE: 815 816 A complete tripartite graph with sets of sizes 817 `5, 6, 8`:: 818 819 sage: g = graphs.CompleteMultipartiteGraph([5, 6, 8]); g 820 Multipartite Graph with set sizes [5, 6, 8]: Graph on 19 vertices 821 822 It clearly has a chromatic number of 3:: 823 824 sage: g.chromatic_number() 825 3 826 """ 827 828 from sage.graphs.graph import Graph 829 g = Graph() 830 for i in l: 831 g = g + CompleteGraph(i) 832 833 g = g.complement() 834 g.name("Multipartite Graph with set sizes "+str(l)) 835 836 return g 837 586 838 def DiamondGraph(): 587 839 """ 588 840 Returns a diamond graph with 4 nodes. 589 841 590 842 A diamond graph is a square with one pair of diagonal nodes 591 843 connected. 592 844 593 845 This constructor depends on NetworkX numeric labeling. 594 846 595 847 PLOTTING: Upon construction, the position dictionary is filled to 596 848 override the spring-layout algorithm. By convention, the diamond 597 849 graph is drawn as a diamond, with the first node on top, second on 598 850 the left, third on the right, and fourth on the bottom; with the 599 851 second and third node connected. 600 852 601 853 EXAMPLES: Construct and show a diamond graph 602 854 603 855 :: 604 856 605 857 sage: g = graphs.DiamondGraph() 606 858 sage: g.show() # long time 607 859 """ … … 609 861 import networkx 610 862 G = networkx.diamond_graph() 611 863 return graph.Graph(G, pos=pos_dict, name="Diamond Graph") 612 864 613 865 def EmptyGraph(): 614 866 """ 615 867 Returns an empty graph (0 nodes and 0 edges). 616 868 617 869 This is useful for constructing graphs by adding edges and vertices 618 870 individually or in a loop. 619 871 620 872 PLOTTING: When plotting, this graph will use the default 621 873 spring-layout algorithm, unless a position dictionary is 622 874 specified. 623 875 624 876 EXAMPLES: Add one vertex to an empty graph and then show:: 625 877 626 878 sage: empty1 = graphs.EmptyGraph() 627 879 sage: empty1.add_vertex() 628 880 0 629 881 sage: empty1.show() # long time 630 882 631 883 Use for loops to build a graph from an empty graph:: 632 884 633 885 sage: empty2 = graphs.EmptyGraph() 634 886 sage: for i in range(5): 635 887 ... empty2.add_vertex() # add 5 nodes, labeled 0-4 … … 802 1054 def GridGraph(dim_list): 803 1055 """ 804 1056 Returns an n-dimensional grid graph. 805 1057 806 1058 INPUT: 807 808 1059 1060 809 1061 - ``dim_list`` - a list of integers representing the 810 1062 number of nodes to extend in each dimension. 811 812 1063 1064 813 1065 PLOTTING: When plotting, this graph will use the default 814 1066 spring-layout algorithm, unless a position dictionary is 815 1067 specified. 816 1068 817 1069 EXAMPLES:: 818 1070 819 1071 sage: G = graphs.GridGraph([2,3,4]) 820 1072 sage: G.show() # long time 821 1073 822 1074 :: 823 1075 824 1076 sage: C = graphs.CubeGraph(4) 825 1077 sage: G = graphs.GridGraph([2,2,2,2]) 826 1078 sage: C.show() # long time … … 837 1089 def HouseGraph(): 838 1090 """ 839 1091 Returns a house graph with 5 nodes. 840 1092 841 1093 A house graph is named for its shape. It is a triangle (roof) over a 842 1094 square (walls). 843 1095 844 1096 This constructor depends on NetworkX numeric labeling. 845 1097 846 1098 PLOTTING: Upon construction, the position dictionary is filled to 847 1099 override the spring-layout algorithm. By convention, the house 848 1100 graph is drawn with the first node in the lower-left corner of the … … 851 1103 and the fourth is in the upper-right corner connecting the roof to 852 1104 the wall. The fifth node is the top of the roof, connected only to 853 1105 the third and fourth. 854 1106 855 1107 EXAMPLES: Construct and show a house graph 856 1108 857 1109 :: 858 1110 859 1111 sage: g = graphs.HouseGraph() 860 1112 sage: g.show() # long time 861 1113 """ … … 863 1115 import networkx 864 1116 G = networkx.house_graph() 865 1117 return graph.Graph(G, pos=pos_dict, name="House Graph") 866 1118 867 1119 def HouseXGraph(): 868 1120 """ 869 1121 Returns a house X graph with 5 nodes. 870 1122 871 1123 A house X graph is a house graph with two additional edges. The 872 1124 upper-right corner is connected to the lower-left. And the 873 1125 upper-left corner is connected to the lower-right. 874 1126 875 1127 This constructor depends on NetworkX numeric labeling. 876 1128 877 1129 PLOTTING: Upon construction, the position dictionary is filled to 878 1130 override the spring-layout algorithm. By convention, the house X 879 1131 graph is drawn with the first node in the lower-left corner of the … … 882 1134 and the fourth is in the upper-right corner connecting the roof to 883 1135 the wall. The fifth node is the top of the roof, connected only to 884 1136 the third and fourth. 885 1137 886 1138 EXAMPLES: Construct and show a house X graph 887 1139 888 1140 :: 889 1141 890 1142 sage: g = graphs.HouseXGraph() 891 1143 sage: g.show() # long time 892 1144 """ … … 898 1150 def KrackhardtKiteGraph(): 899 1151 """ 900 1152 Returns a Krackhardt kite graph with 10 nodes. 901 1153 902 1154 The Krackhardt kite graph was originally developed by David 903 1155 Krackhardt for the purpose of studying social networks. It is used 904 1156 to show the distinction between: degree centrality, betweeness 905 1157 centrality, and closeness centrality. For more information read the 906 1158 plotting section below in conjunction with the example. 907 1159 908 1160 REFERENCES: 909 1161 910 1162 - [1] Kreps, V. (2002). "Social Network Analysis". [Online] Available: 911 1163 http://www.fsu.edu/~spap/water/network/intro.htm [2007, 912 1164 January 17] 913 1165 914 1166 This constructor depends on NetworkX numeric labeling. 915 1167 916 1168 PLOTTING: Upon construction, the position dictionary is filled to 917 1169 override the spring-layout algorithm. By convention, the graph is 918 1170 drawn left to right, in top to bottom row sequence of [2, 3, 2, 1, … … 926 1178 third row and have degree = 5. These nodes have the shortest path 927 1179 to all other nodes in the graph (i.e.: Closeness Centrality). 928 1180 Please execute the example for visualization. 929 1181 930 1182 EXAMPLE: Construct and show a Krackhardt kite graph 931 1183 932 1184 :: 933 1185 934 1186 sage: g = graphs.KrackhardtKiteGraph() 935 1187 sage: g.show() # long time 936 1188 """ … … 942 1194 def LadderGraph(n): 943 1195 """ 944 1196 Returns a ladder graph with 2\*n nodes. 945 1197 946 1198 A ladder graph is a basic structure that is typically displayed as 947 1199 a ladder, i.e.: two parallel path graphs connected at each 948 1200 corresponding node pair. 949 1201 950 1202 This constructor depends on NetworkX numeric labels. 951 1203 952 1204 PLOTTING: Upon construction, the position dictionary is filled to 953 1205 override the spring-layout algorithm. By convention, each ladder 954 1206 graph will be displayed horizontally, with the first n nodes 955 1207 displayed left to right on the top horizontal line. 956 1208 957 1209 EXAMPLES: Construct and show a ladder graph with 14 nodes 958 1210 959 1211 :: 960 1212 961 1213 sage: g = graphs.LadderGraph(7) 962 1214 sage: g.show() # long time 963 1215 964 1216 Create several ladder graphs in a Sage graphics array 965 1217 966 1218 :: 967 1219 968 1220 sage: g = [] 969 1221 sage: j = [] 970 1222 sage: for i in range(9): … … 993 1245 def LollipopGraph(n1, n2): 994 1246 """ 995 1247 Returns a lollipop graph with n1+n2 nodes. 996 1248 997 1249 A lollipop graph is a path graph (order n2) connected to a complete 998 1250 graph (order n1). (A barbell graph minus one of the bells). 999 1251 1000 1252 This constructor depends on NetworkX numeric labels. 1001 1253 1002 1254 PLOTTING: Upon construction, the position dictionary is filled to 1003 1255 override the spring-layout algorithm. By convention, the complete 1004 1256 graph will be drawn in the lower-left corner with the (n1)th node 1005 1257 at a 45 degree angle above the right horizontal center of the 1006 1258 complete graph, leading directly into the path graph. 1007 1259 1008 1260 EXAMPLES: Construct and show a lollipop graph Candy = 13, Stick = 1009 1261 4 1010 1262 1011 1263 :: 1012 1264 1013 1265 sage: g = graphs.LollipopGraph(13,4) 1014 1266 sage: g.show() # long time 1015 1267 1016 1268 Create several lollipop graphs in a Sage graphics array 1017 1269 1018 1270 :: 1019 1271 1020 1272 sage: g = [] 1021 1273 sage: j = [] 1022 1274 sage: for i in range(6): … … 1033 1285 sage: G.show() # long time 1034 1286 """ 1035 1287 pos_dict = {} 1036 1288 1037 1289 for i in range(n1): 1038 1290 x = float(cos((pi/4) - ((2*pi)/n1)*i) - n2/2 - 1) 1039 1291 y = float(sin((pi/4) - ((2*pi)/n1)*i) - n2/2 - 1) … … 1043 1295 x = float(i - n1 - n2/2 + 1) 1044 1296 y = float(i - n1 - n2/2 + 1) 1045 1297 pos_dict[i] = (x,y) 1046 1298 1047 1299 import networkx 1048 1300 G = networkx.lollipop_graph(n1,n2) 1049 1301 return graph.Graph(G, pos=pos_dict, name="Lollipop Graph") 1050 1302 1051 1303 def PathGraph(n, pos=None): 1052 1304 """ 1053 1305 Returns a path graph with n nodes. Pos argument takes a string 1054 1306 which is either 'circle' or 'line', (otherwise the default is 1055 1307 used). See the plotting section below for more detail. 1056 1308 1057 1309 A path graph is a graph where all inner nodes are connected to 1058 1310 their two neighbors and the two end-nodes are connected to their 1059 1311 one inner neighbors. (i.e.: a cycle graph without the first and 1060 1312 last node connected). 1061 1313 1062 1314 This constructor depends on NetworkX numeric labels. 1063 1315 1064 1316 PLOTTING: Upon construction, the position dictionary is filled to 1065 1317 override the spring-layout algorithm. By convention, the graph may 1066 1318 be drawn in one of two ways: The 'line' argument will draw the … … 1072 1324 circle in a clockwise manner. By default (without an appropriate 1073 1325 string argument) the graph will be drawn as a 'circle' if 10 n 41 1074 1326 and as a 'line' for all other n. 1075 1327 1076 1328 EXAMPLES: Show default drawing by size: 'line': n 11 1077 1329 1078 1330 :: 1079 1331 1080 1332 sage: p = graphs.PathGraph(10) 1081 1333 sage: p.show() # long time 1082 1334 1083 1335 'circle': 10 n 41 1084 1336 1085 1337 :: 1086 1338 1087 1339 sage: q = graphs.PathGraph(25) 1088 1340 sage: q.show() # long time 1089 1341 1090 1342 'line': n 40 1091 1343 1092 1344 :: 1093 1345 1094 1346 sage: r = graphs.PathGraph(55) 1095 1347 sage: r.show() # long time 1096 1348 1097 1349 Override the default drawing:: 1098 1350 1099 1351 sage: s = graphs.PathGraph(5,'circle') 1100 1352 sage: s.show() # long time 1101 1353 """ 1102 1354 pos_dict = {} 1103 1355 1104 1356 # Choose appropriate drawing pattern 1105 1357 circle = False 1106 1358 if pos == "circle": circle = True 1107 1359 elif pos == "line": circle = False 1108 1360 # Otherwise use default by size of n 1109 1361 elif 10 < n < 41: circle = True 1110 1362 1111 1363 # Draw 'circle' 1112 1364 if circle: 1113 1365 for i in range(n): … … 1120 1372 rem = n%10 # remainder to appear on last row 1121 1373 rows = n//10 # number of rows (not counting last row) 1122 1374 lr = True # left to right 1123 1375 1124 1376 for i in range(rows): # note that rows doesn't include last row 1125 1377 y = -i 1126 1378 for j in range(10): 1127 1379 if lr: 1128 1380 x = j 1129 else: 1381 else: 1130 1382 x = 9 - j 1131 1383 pos_dict[counter] = (x,y) 1132 1384 counter += 1 … … 1136 1388 for j in range(rem): # last row 1137 1389 if lr: 1138 1390 x = j 1139 else: 1391 else: 1140 1392 x = 9 - j 1141 1393 pos_dict[counter] = (x,y) 1142 1394 counter += 1 … … 1148 1400 def StarGraph(n): 1149 1401 """ 1150 1402 Returns a star graph with n+1 nodes. 1151 1403 1152 1404 A Star graph is a basic structure where one node is connected to 1153 1405 all other nodes. 1154 1406 1155 1407 This constructor is dependent on NetworkX numeric labels. 1156 1408 1157 1409 PLOTTING: Upon construction, the position dictionary is filled to 1158 1410 override the spring-layout algorithm. By convention, each star 1159 1411 graph will be displayed with the first (0) node in the center, the 1160 1412 second node (1) at the top, with the rest following in a 1161 1413 counterclockwise manner. (0) is the node connected to all other 1162 1414 nodes. 1163 1415 1164 1416 The star graph is a good opportunity to compare efficiency of 1165 1417 filling a position dictionary vs. using the spring-layout algorithm 1166 1418 for plotting. As far as display, the spring-layout should push all 1167 1419 other nodes away from the (0) node, and thus look very similar to 1168 1420 this constructor's positioning. 1169 1421 1170 1422 EXAMPLES:: 1171 1423 1172 1424 sage: import networkx 1173 1425 1174 1426 Compare the plots:: 1175 1427 1176 1428 sage: n = networkx.star_graph(23) 1177 1429 sage: spring23 = Graph(n) 1178 1430 sage: posdict23 = graphs.StarGraph(23) 1179 1431 sage: spring23.show() # long time 1180 1432 sage: posdict23.show() # long time 1181 1433 1182 1434 View many star graphs as a Sage Graphics Array 1183 1435 1184 1436 With this constructor (i.e., the position dictionary filled) 1185 1437 1186 1438 :: 1187 1439 1188 1440 sage: g = [] 1189 1441 sage: j = [] 1190 1442 sage: for i in range(9): … … 1199 1451 ... 1200 1452 sage: G = sage.plot.graphics.GraphicsArray(j) 1201 1453 sage: G.show() # long time 1202 1454 1203 1455 Compared to plotting with the spring-layout algorithm 1204 1456 1205 1457 :: 1206 1458 1207 1459 sage: g = [] 1208 1460 sage: j = [] 1209 1461 sage: for i in range(9): 1210 ... spr = networkx.star_graph(i+3) 1462 ... spr = networkx.star_graph(i+3) 1211 1463 ... k = Graph(spr) 1212 1464 ... g.append(k) 1213 1465 ... … … 1233 1485 def WheelGraph(n): 1234 1486 """ 1235 1487 Returns a Wheel graph with n nodes. 1236 1488 1237 1489 A Wheel graph is a basic structure where one node is connected to 1238 1490 all other nodes and those (outer) nodes are connected cyclically. 1239 1491 1240 1492 This constructor depends on NetworkX numeric labels. 1241 1493 1242 1494 PLOTTING: Upon construction, the position dictionary is filled to 1243 1495 override the spring-layout algorithm. By convention, each wheel 1244 1496 graph will be displayed with the first (0) node in the center, the 1245 1497 second node at the top, and the rest following in a 1246 1498 counterclockwise manner. 1247 1499 1248 1500 With the wheel graph, we see that it doesn't take a very large n at 1249 1501 all for the spring-layout to give a counter-intuitive display. (See 1250 1502 Graphics Array examples below). 1251 1503 1252 1504 EXAMPLES: We view many wheel graphs with a Sage Graphics Array, 1253 1505 first with this constructor (i.e., the position dictionary 1254 1506 filled):: 1255 1507 1256 1508 sage: g = [] 1257 1509 sage: j = [] 1258 1510 sage: for i in range(9): … … 1267 1519 ... 1268 1520 sage: G = sage.plot.graphics.GraphicsArray(j) 1269 1521 sage: G.show() # long time 1270 1522 1271 1523 Next, using the spring-layout algorithm:: 1272 1524 1273 1525 sage: import networkx 1274 1526 sage: g = [] 1275 1527 sage: j = [] 1276 1528 sage: for i in range(9): 1277 ... spr = networkx.wheel_graph(i+3) 1529 ... spr = networkx.wheel_graph(i+3) 1278 1530 ... k = Graph(spr) 1279 1531 ... g.append(k) 1280 1532 ... … … 1286 1538 ... 1287 1539 sage: G = sage.plot.graphics.GraphicsArray(j) 1288 1540 sage: G.show() # long time 1289 1541 1290 1542 Compare the plotting:: 1291 1543 1292 1544 sage: n = networkx.wheel_graph(23) 1293 1545 sage: spring23 = Graph(n) 1294 1546 sage: posdict23 = graphs.WheelGraph(23) … … 1301 1553 x = float(cos((pi/2) + ((2*pi)/(n-1))*(i-1))) 1302 1554 y = float(sin((pi/2) + ((2*pi)/(n-1))*(i-1))) 1303 1555 pos_dict[i] = (x,y) 1304 import networkx 1556 import networkx 1305 1557 G = networkx.wheel_graph(n) 1306 1558 return graph.Graph(G, pos=pos_dict, name="Wheel graph") -
sage/graphs/generators/families.py
diff --git a/sage/graphs/generators/families.py b/sage/graphs/generators/families.py
a b 501 501 raise ValueError( 502 502 "Invalid number of symbols to permute, n should be >= 1") 503 503 if n == 1: 504 from sage.graphs.generators. familiesimport CompleteGraph504 from sage.graphs.generators.basic import CompleteGraph 505 505 return graph.Graph(CompleteGraph(n), name="Bubble sort") 506 506 from sage.combinat.permutation import Permutations 507 507 #create set from which to permute … … 629 629 G.add_edges([(v,(v-j)%n) for j in adjacency]) 630 630 return G 631 631 632 def CompleteGraph(n):633 """634 Returns a complete graph on n nodes.635 636 A Complete Graph is a graph in which all nodes are connected to all637 other nodes.638 639 This constructor is dependent on vertices numbered 0 through n-1 in640 NetworkX complete_graph()641 642 PLOTTING: Upon construction, the position dictionary is filled to643 override the spring-layout algorithm. By convention, each complete644 graph will be displayed with the first (0) node at the top, with645 the rest following in a counterclockwise manner.646 647 In the complete graph, there is a big difference visually in using648 the spring-layout algorithm vs. the position dictionary used in649 this constructor. The position dictionary flattens the graph,650 making it clear which nodes an edge is connected to. But the651 complete graph offers a good example of how the spring-layout652 works. The edges push outward (everything is connected), causing653 the graph to appear as a 3-dimensional pointy ball. (See examples654 below).655 656 EXAMPLES: We view many Complete graphs with a Sage Graphics Array,657 first with this constructor (i.e., the position dictionary658 filled)::659 660 sage: g = []661 sage: j = []662 sage: for i in range(9):663 ... k = graphs.CompleteGraph(i+3)664 ... g.append(k)665 ...666 sage: for i in range(3):667 ... n = []668 ... for m in range(3):669 ... n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))670 ... j.append(n)671 ...672 sage: G = sage.plot.graphics.GraphicsArray(j)673 sage: G.show() # long time674 675 We compare to plotting with the spring-layout algorithm::676 677 sage: import networkx678 sage: g = []679 sage: j = []680 sage: for i in range(9):681 ... spr = networkx.complete_graph(i+3)682 ... k = Graph(spr)683 ... g.append(k)684 ...685 sage: for i in range(3):686 ... n = []687 ... for m in range(3):688 ... n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))689 ... j.append(n)690 ...691 sage: G = sage.plot.graphics.GraphicsArray(j)692 sage: G.show() # long time693 694 Compare the constructors (results will vary)695 696 ::697 698 sage: import networkx699 sage: t = cputime()700 sage: n = networkx.complete_graph(389); spring389 = Graph(n)701 sage: cputime(t) # random702 0.59203700000000126703 sage: t = cputime()704 sage: posdict389 = graphs.CompleteGraph(389)705 sage: cputime(t) # random706 0.6680419999999998707 708 We compare plotting::709 710 sage: import networkx711 sage: n = networkx.complete_graph(23)712 sage: spring23 = Graph(n)713 sage: posdict23 = graphs.CompleteGraph(23)714 sage: spring23.show() # long time715 sage: posdict23.show() # long time716 """717 pos_dict = {}718 for i in range(n):719 x = float(cos((pi/2) + ((2*pi)/n)*i))720 y = float(sin((pi/2) + ((2*pi)/n)*i))721 pos_dict[i] = (x,y)722 import networkx723 G = networkx.complete_graph(n)724 return graph.Graph(G, pos=pos_dict, name="Complete graph")725 726 def CompleteBipartiteGraph(n1, n2):727 """728 Returns a Complete Bipartite Graph sized n1+n2, with each of the729 nodes [0,(n1-1)] connected to each of the nodes [n1,(n2-1)] and730 vice versa.731 732 A Complete Bipartite Graph is a graph with its vertices partitioned733 into two groups, V1 and V2. Each v in V1 is connected to every v in734 V2, and vice versa.735 736 PLOTTING: Upon construction, the position dictionary is filled to737 override the spring-layout algorithm. By convention, each complete738 bipartite graph will be displayed with the first n1 nodes on the739 top row (at y=1) from left to right. The remaining n2 nodes appear740 at y=0, also from left to right. The shorter row (partition with741 fewer nodes) is stretched to the same length as the longer row,742 unless the shorter row has 1 node; in which case it is centered.743 The x values in the plot are in domain [0,maxn1,n2].744 745 In the Complete Bipartite graph, there is a visual difference in746 using the spring-layout algorithm vs. the position dictionary used747 in this constructor. The position dictionary flattens the graph and748 separates the partitioned nodes, making it clear which nodes an749 edge is connected to. The Complete Bipartite graph plotted with the750 spring-layout algorithm tends to center the nodes in n1 (see751 spring_med in examples below), thus overlapping its nodes and752 edges, making it typically hard to decipher.753 754 Filling the position dictionary in advance adds O(n) to the755 constructor. Feel free to race the constructors below in the756 examples section. The much larger difference is the time added by757 the spring-layout algorithm when plotting. (Also shown in the758 example below). The spring model is typically described as759 `O(n^3)`, as appears to be the case in the NetworkX source760 code.761 762 EXAMPLES: Two ways of constructing the complete bipartite graph,763 using different layout algorithms::764 765 sage: import networkx766 sage: n = networkx.complete_bipartite_graph(389,157); spring_big = Graph(n) # long time767 sage: posdict_big = graphs.CompleteBipartiteGraph(389,157) # long time768 769 Compare the plotting::770 771 sage: n = networkx.complete_bipartite_graph(11,17)772 sage: spring_med = Graph(n)773 sage: posdict_med = graphs.CompleteBipartiteGraph(11,17)774 775 Notice here how the spring-layout tends to center the nodes of n1776 777 ::778 779 sage: spring_med.show() # long time780 sage: posdict_med.show() # long time781 782 View many complete bipartite graphs with a Sage Graphics Array,783 with this constructor (i.e., the position dictionary filled)::784 785 sage: g = []786 sage: j = []787 sage: for i in range(9):788 ... k = graphs.CompleteBipartiteGraph(i+1,4)789 ... g.append(k)790 ...791 sage: for i in range(3):792 ... n = []793 ... for m in range(3):794 ... n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))795 ... j.append(n)796 ...797 sage: G = sage.plot.graphics.GraphicsArray(j)798 sage: G.show() # long time799 800 We compare to plotting with the spring-layout algorithm::801 802 sage: g = []803 sage: j = []804 sage: for i in range(9):805 ... spr = networkx.complete_bipartite_graph(i+1,4)806 ... k = Graph(spr)807 ... g.append(k)808 ...809 sage: for i in range(3):810 ... n = []811 ... for m in range(3):812 ... n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))813 ... j.append(n)814 ...815 sage: G = sage.plot.graphics.GraphicsArray(j)816 sage: G.show() # long time817 818 Trac ticket #12155::819 820 sage: graphs.CompleteBipartiteGraph(5,6).complement()821 complement(Complete bipartite graph): Graph on 11 vertices822 """823 pos_dict = {}824 c1 = 1 # scaling factor for top row825 c2 = 1 # scaling factor for bottom row826 c3 = 0 # pad to center if top row has 1 node827 c4 = 0 # pad to center if bottom row has 1 node828 if n1 > n2:829 if n2 == 1:830 c4 = (n1-1)/2831 else:832 c2 = ((n1-1)/(n2-1))833 elif n2 > n1:834 if n1 == 1:835 c3 = (n2-1)/2836 else:837 c1 = ((n2-1)/(n1-1))838 for i in range(n1):839 x = c1*i + c3840 y = 1841 pos_dict[i] = (x,y)842 for i in range(n1+n2)[n1:]:843 x = c2*(i-n1) + c4844 y = 0845 pos_dict[i] = (x,y)846 import networkx847 from sage.graphs.graph import Graph848 G = networkx.complete_bipartite_graph(n1,n2)849 return Graph(G, pos=pos_dict, name="Complete bipartite graph")850 851 def CompleteMultipartiteGraph(l):852 r"""853 Returns a complete multipartite graph.854 855 INPUT:856 857 - ``l`` -- a list of integers : the respective sizes858 of the components.859 860 EXAMPLE:861 862 A complete tripartite graph with sets of sizes863 `5, 6, 8`::864 865 sage: g = graphs.CompleteMultipartiteGraph([5, 6, 8]); g866 Multipartite Graph with set sizes [5, 6, 8]: Graph on 19 vertices867 868 It clearly has a chromatic number of 3::869 870 sage: g.chromatic_number()871 3872 """873 874 from sage.graphs.graph import Graph875 from sage.graphs.generators.families import CompleteGraph876 g = Graph()877 for i in l:878 g = g + CompleteGraph(i)879 880 g = g.complement()881 g.name("Multipartite Graph with set sizes "+str(l))882 883 return g884 885 632 def CubeGraph(n): 886 633 r""" 887 634 Returns the hypercube in `n` dimensions. … … 1124 871 sage: set([g.laplacian_matrix(normalized=True).charpoly() for g in g_list]) # long time (7s on sage.math, 2011) 1125 872 set([x^8 - 8*x^7 + 4079/150*x^6 - 68689/1350*x^5 + 610783/10800*x^4 - 120877/3240*x^3 + 1351/100*x^2 - 931/450*x]) 1126 873 """ 874 from sage.graphs.generators.basic import CompleteGraph 1127 875 if len(partition)<1: 1128 876 raise ValueError, "partition must be a nonempty list of positive integers" 1129 877 n=q+sum(partition) … … 2094 1842 raise ValueError('The number of levels must be >= 1.') 2095 1843 2096 1844 from sage.graphs.graph_plot import _circle_embedding 2097 from sage.graphs.graph_plot import GraphGenerators2098 1845 2099 1846 # Creating the Balanced tree, which contains most edges already 2100 g = GraphGenerators().BalancedTree(2,k-1)1847 g = BalancedTree(2,k-1) 2101 1848 g.name('Ringed Tree on '+str(k)+' levels') 2102 1849 2103 1850 # We consider edges layer by layer -
sage/graphs/generators/random.py
diff --git a/sage/graphs/generators/random.py b/sage/graphs/generators/random.py
a b 114 114 if seed is None: 115 115 seed = current_randstate().long_seed() 116 116 if p == 1: 117 from sage.graphs.generators. familiesimport CompleteGraph117 from sage.graphs.generators.basic import CompleteGraph 118 118 return CompleteGraph(n) 119 119 120 120 if method == 'networkx': -
sage/graphs/graph_generators.py
diff --git a/sage/graphs/graph_generators.py b/sage/graphs/graph_generators.py
a b 55 55 "CircularLadderGraph", 56 56 "ClawGraph", 57 57 "CycleGraph", 58 "CompleteBipartiteGraph", 59 "CompleteGraph", 60 "CompleteMultipartiteGraph", 58 61 "DiamondGraph", 59 62 "EmptyGraph", 60 63 "Grid2dGraph", … … 140 143 ["BalancedTree", 141 144 "BubbleSortGraph", 142 145 "CirculantGraph", 143 "CompleteBipartiteGraph",144 "CompleteGraph",145 146 "CubeGraph", 146 147 "FibonacciTree", 147 148 "FriendshipGraph", … … 909 910 BalancedTree = staticmethod(sage.graphs.generators.families.BalancedTree) 910 911 BubbleSortGraph = staticmethod(sage.graphs.generators.families.BubbleSortGraph) 911 912 CirculantGraph = staticmethod(sage.graphs.generators.families.CirculantGraph) 912 CompleteGraph = staticmethod(sage.graphs.generators.families.CompleteGraph)913 CompleteBipartiteGraph = staticmethod(sage.graphs.generators.families.CompleteBipartiteGraph)914 CompleteMultipartiteGraph = staticmethod(sage.graphs.generators.families.CompleteMultipartiteGraph)915 913 CubeGraph = staticmethod(sage.graphs.generators.families.CubeGraph) 916 914 DorogovtsevGoltsevMendesGraph = staticmethod(sage.graphs.generators.families.DorogovtsevGoltsevMendesGraph) 917 915 FriendshipGraph = staticmethod(sage.graphs.generators.families.FriendshipGraph) … … 992 990 CircularLadderGraph = staticmethod(sage.graphs.generators.basic.CircularLadderGraph) 993 991 ClawGraph = staticmethod(sage.graphs.generators.basic.ClawGraph) 994 992 CycleGraph = staticmethod(sage.graphs.generators.basic.CycleGraph) 993 CompleteGraph = staticmethod(sage.graphs.generators.basic.CompleteGraph) 994 CompleteBipartiteGraph = staticmethod(sage.graphs.generators.basic.CompleteBipartiteGraph) 995 CompleteMultipartiteGraph= staticmethod(sage.graphs.generators.basic.CompleteMultipartiteGraph) 995 996 DiamondGraph = staticmethod(sage.graphs.generators.basic.DiamondGraph) 996 997 EmptyGraph = staticmethod(sage.graphs.generators.basic.EmptyGraph) 997 998 Grid2dGraph = staticmethod(sage.graphs.generators.basic.Grid2dGraph)