Ticket #11182: trac_11182flat.patch
File trac_11182flat.patch, 16.0 KB (added by , 10 years ago) 


sage/graphs/bipartite_graph.py
# HG changeset patch # User Robert L. Miller <rlm@rlmiller.org> # Date 1302639230 25200 # Node ID cf534bb0ee10ccdd3dd2436cb7defc63ee46cd75 # Parent 9418a12e694afd8af736d4892d1a66a7d6145641 #11181: edge labels should be unique diff r 9418a12e694a r cf534bb0ee10 sage/graphs/bipartite_graph.py
a b 603 603 sage: B.left 604 604 set([2]) 605 605 sage: B.edges() 606 [(1, 2, {}), (2, 3, {})]606 [(1, 2, None), (2, 3, None)] 607 607 sage: B.delete_vertex(3) 608 608 sage: B.right 609 609 set([1]) 610 610 sage: B.edges() 611 [(1, 2, {})]611 [(1, 2, None)] 612 612 sage: B.delete_vertex(0) 613 613 Traceback (most recent call last): 614 614 ... … … 671 671 sage: B.right 672 672 set([1]) 673 673 sage: B.edges() 674 [(1, 2, {})]674 [(1, 2, None)] 675 675 sage: B.delete_vertices([0]) 676 676 Traceback (most recent call last): 677 677 ... … … 976 976 ... if b != b2: 977 977 ... print "Load/save failed for code with edges:" 978 978 ... print b.edges() 979 ... print b2.edges() 979 980 ... except: 980 981 ... print "Exception encountered for graph of order "+ str(order) 981 982 ... print "with edges: " 
sage/graphs/digraph.py
diff r 9418a12e694a r cf534bb0ee10 sage/graphs/digraph.py
a b 83 83 84 84 INPUT: 85 85 86  ``data``  can be any of the following :86  ``data``  can be any of the following (see the ``format`` keyword): 87 87 88 88 #. A dictionary of dictionaries 89 89 … … 93 93 94 94 #. A Sage adjacency matrix or incidence matrix 95 95 96 #. A pygraphviz agraph96 #. A pygraphviz graph 97 97 98 98 #. A SciPy sparse matrix 99 99 … … 133 133  ``'weighted_adjacency_matrix'``  a square Sage 134 134 matrix M, with M[i,j] equal to the weight of the single edge {i,j}. 135 135 Given this format, weighted is ignored (assumed True). 136 137  ``NX``  data must be a NetworkX DiGraph. 138 139 .. NOTE:: 140 141 As Sage's default edge labels is ``None`` while NetworkX uses 142 ``{}``, the ``{}`` labels of a NetworkX digraph are automatically 143 set to ``None`` when it is converted to a Sage graph. This 144 behaviour can be overruled by setting the keyword 145 ``convert_empty_dict_labels_to_None`` to ``False`` (it is 146 ``True`` by default). 136 147 137 148  ``boundary``  a list of boundary vertices, if none, 138 149 digraph is considered as a 'digraph without boundary' … … 461 472 format = 'NX' 462 473 463 474 # At this point, format has been set. 475 476 # adjust for empty dicts instead of None in NetworkX default edge labels 477 kwds.setdefault('convert_empty_dict_labels_to_None', (format == 'NX')) 478 464 479 verts = None 465 480 466 481 if format == 'dig6': … … 706 721 if f(uu,vv): 707 722 self.add_edge(uu,vv) 708 723 elif format == 'dict_of_dicts': 709 for u in data: 710 for v in data[u]: 711 if multiedges: 712 self.add_edges([(u,v,l) for l in data[u][v]]) 713 else: 714 self.add_edge((u,v,data[u][v])) 724 if kwds.get('convert_empty_dict_labels_to_None', False): 725 for u in data: 726 for v in data[u]: 727 if multiedges: 728 self.add_edges([(u,v,l) for l in data[u][v]]) 729 else: 730 self.add_edge((u,v,data[u][v] if data[u][v] != {} else None)) 731 else: 732 for u in data: 733 for v in data[u]: 734 if multiedges: 735 self.add_edges([(u,v,l) for l in data[u][v]]) 736 else: 737 self.add_edge((u,v,data[u][v])) 715 738 elif format == 'dict_of_lists': 716 739 for u in data: 717 740 for v in data[u]: 
sage/graphs/generic_graph.py
diff r 9418a12e694a r cf534bb0ee10 sage/graphs/generic_graph.py
a b 2107 2107 4 2108 2108 sage: weight = lambda e: 1 / ((e[0] + 1) * (e[1] + 1)) 2109 2109 sage: g.min_spanning_tree(weight_function=weight) 2110 [(3, 4, {}), (2, 4, {}), (1, 4, {}), (0, 4, {})]2110 [(3, 4, None), (2, 4, None), (1, 4, None), (0, 4, None)] 2111 2111 sage: g = graphs.PetersenGraph() 2112 2112 sage: g.allow_multiple_edges(True) 2113 2113 sage: g.weighted(True) … … 2119 2119 2120 2120 sage: g = graphs.CompleteGraph(5) 2121 2121 sage: g.min_spanning_tree(algorithm='Prim_edge', starting_vertex=2, weight_function=weight) 2122 [(2, 4, {}), (3, 4, {}), (1, 4, {}), (0, 4, {})]2122 [(2, 4, None), (3, 4, None), (1, 4, None), (0, 4, None)] 2123 2123 sage: g.min_spanning_tree(algorithm='Prim_fringe', starting_vertex=2, weight_function=weight) 2124 2124 [(2, 4), (4, 3), (4, 1), (4, 0)] 2125 2125 """ … … 7253 7253 sage: g=graphs.CycleGraph(3) 7254 7254 sage: g.merge_vertices([0,1]) 7255 7255 sage: g.edges() 7256 [(0, 2, {})]7256 [(0, 2, None)] 7257 7257 sage: # With a Multigraph : 7258 7258 sage: g=graphs.CycleGraph(3) 7259 7259 sage: g.allow_multiple_edges(True) 7260 7260 sage: g.merge_vertices([0,1]) 7261 sage: g.edges( )7262 [(0, 2 , {}), (0, 2, {})]7261 sage: g.edges(labels=False) 7262 [(0, 2), (0, 2)] 7263 7263 sage: P=graphs.PetersenGraph() 7264 7264 sage: P.merge_vertices([5,7]) 7265 7265 sage: P.vertices() … … 7840 7840 EXAMPLES:: 7841 7841 7842 7842 sage: graphs.DodecahedralGraph().edges() 7843 [(0, 1, {}), (0, 10, {}), (0, 19, {}), (1, 2, {}), (1, 8, {}), (2, 3, {}), (2, 6, {}), (3, 4, {}), (3, 19, {}), (4, 5, {}), (4, 17, {}), (5, 6, {}), (5, 15, {}), (6, 7, {}), (7, 8, {}), (7, 14, {}), (8, 9, {}), (9, 10, {}), (9, 13, {}), (10, 11, {}), (11, 12, {}), (11, 18, {}), (12, 13, {}), (12, 16, {}), (13, 14, {}), (14, 15, {}), (15, 16, {}), (16, 17, {}), (17, 18, {}), (18, 19, {})]7843 [(0, 1, None), (0, 10, None), (0, 19, None), (1, 2, None), (1, 8, None), (2, 3, None), (2, 6, None), (3, 4, None), (3, 19, None), (4, 5, None), (4, 17, None), (5, 6, None), (5, 15, None), (6, 7, None), (7, 8, None), (7, 14, None), (8, 9, None), (9, 10, None), (9, 13, None), (10, 11, None), (11, 12, None), (11, 18, None), (12, 13, None), (12, 16, None), (13, 14, None), (14, 15, None), (15, 16, None), (16, 17, None), (17, 18, None), (18, 19, None)] 7844 7844 7845 7845 :: 7846 7846 … … 7851 7851 7852 7852 sage: D = graphs.DodecahedralGraph().to_directed() 7853 7853 sage: D.edges() 7854 [(0, 1, {}), (0, 10, {}), (0, 19, {}), (1, 0, {}), (1, 2, {}), (1, 8, {}), (2, 1, {}), (2, 3, {}), (2, 6, {}), (3, 2, {}), (3, 4, {}), (3, 19, {}), (4, 3, {}), (4, 5, {}), (4, 17, {}), (5, 4, {}), (5, 6, {}), (5, 15, {}), (6, 2, {}), (6, 5, {}), (6, 7, {}), (7, 6, {}), (7, 8, {}), (7, 14, {}), (8, 1, {}), (8, 7, {}), (8, 9, {}), (9, 8, {}), (9, 10, {}), (9, 13, {}), (10, 0, {}), (10, 9, {}), (10, 11, {}), (11, 10, {}), (11, 12, {}), (11, 18, {}), (12, 11, {}), (12, 13, {}), (12, 16, {}), (13, 9, {}), (13, 12, {}), (13, 14, {}), (14, 7, {}), (14, 13, {}), (14, 15, {}), (15, 5, {}), (15, 14, {}), (15, 16, {}), (16, 12, {}), (16, 15, {}), (16, 17, {}), (17, 4, {}), (17, 16, {}), (17, 18, {}), (18, 11, {}), (18, 17, {}), (18, 19, {}), (19, 0, {}), (19, 3, {}), (19, 18, {})]7854 [(0, 1, None), (0, 10, None), (0, 19, None), (1, 0, None), (1, 2, None), (1, 8, None), (2, 1, None), (2, 3, None), (2, 6, None), (3, 2, None), (3, 4, None), (3, 19, None), (4, 3, None), (4, 5, None), (4, 17, None), (5, 4, None), (5, 6, None), (5, 15, None), (6, 2, None), (6, 5, None), (6, 7, None), (7, 6, None), (7, 8, None), (7, 14, None), (8, 1, None), (8, 7, None), (8, 9, None), (9, 8, None), (9, 10, None), (9, 13, None), (10, 0, None), (10, 9, None), (10, 11, None), (11, 10, None), (11, 12, None), (11, 18, None), (12, 11, None), (12, 13, None), (12, 16, None), (13, 9, None), (13, 12, None), (13, 14, None), (14, 7, None), (14, 13, None), (14, 15, None), (15, 5, None), (15, 14, None), (15, 16, None), (16, 12, None), (16, 15, None), (16, 17, None), (17, 4, None), (17, 16, None), (17, 18, None), (18, 11, None), (18, 17, None), (18, 19, None), (19, 0, None), (19, 3, None), (19, 18, None)] 7855 7855 sage: D.edges(labels = False) 7856 7856 [(0, 1), (0, 10), (0, 19), (1, 0), (1, 2), (1, 8), (2, 1), (2, 3), (2, 6), (3, 2), (3, 4), (3, 19), (4, 3), (4, 5), (4, 17), (5, 4), (5, 6), (5, 15), (6, 2), (6, 5), (6, 7), (7, 6), (7, 8), (7, 14), (8, 1), (8, 7), (8, 9), (9, 8), (9, 10), (9, 13), (10, 0), (10, 9), (10, 11), (11, 10), (11, 12), (11, 18), (12, 11), (12, 13), (12, 16), (13, 9), (13, 12), (13, 14), (14, 7), (14, 13), (14, 15), (15, 5), (15, 14), (15, 16), (16, 12), (16, 15), (16, 17), (17, 4), (17, 16), (17, 18), (18, 11), (18, 17), (18, 19), (19, 0), (19, 3), (19, 18)] 7857 7857 … … 7861 7861 7862 7862 sage: G=graphs.CycleGraph(5) 7863 7863 sage: G.edges(key = lambda x: (x[1],x[0])) 7864 [(0, 1, {}), (1, 2, {}), (2, 3, {}), (3, 4, {}), (0, 4, {})]7864 [(0, 1, None), (1, 2, None), (2, 3, None), (3, 4, None), (0, 4, None)] 7865 7865 7866 7866 We set the labels to characters and then perform a default sort 7867 7867 followed by a sort according to the labels. :: … … 7935 7935 7936 7936 sage: G = graphs.DiamondGraph() 7937 7937 sage: G.edge_boundary([0,1]) 7938 [(0, 2, {}), (1, 2, {}), (1, 3, {})]7938 [(0, 2, None), (1, 2, None), (1, 3, None)] 7939 7939 sage: G.edge_boundary([0], [0]) 7940 7940 [] 7941 7941 sage: G.edge_boundary([2], [0]) 7942 [(0, 2, {})]7942 [(0, 2, None)] 7943 7943 """ 7944 7944 vertices1 = set([v for v in vertices1 if v in self]) 7945 7945 if self._directed: … … 14319 14319 Relabeling using an injective function:: 14320 14320 14321 14321 sage: G.edges() 14322 [(0, 1, {}), (1, 2, {})]14322 [(0, 1, None), (1, 2, None)] 14323 14323 sage: H = G.relabel(lambda i: i+10, inplace=False) 14324 14324 sage: H.vertices() 14325 14325 [10, 11, 12] 14326 14326 sage: H.edges() 14327 [(10, 11, {}), (11, 12, {})]14327 [(10, 11, None), (11, 12, None)] 14328 14328 14329 14329 Relabeling using a non injective function is not yet supported:: 14330 14330 14331 14331 sage: G.edges() 14332 [(0, 1, {}), (1, 2, {})]14332 [(0, 1, None), (1, 2, None)] 14333 14333 sage: G.relabel(lambda i: 0, inplace=False) 14334 14334 Traceback (most recent call last): 14335 14335 ... 
sage/graphs/graph.py
diff r 9418a12e694a r cf534bb0ee10 sage/graphs/graph.py
a b 75 75 Graph Format 76 76  77 77 78 The Sage Graph Class: NetworkX plus79 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~80 81 Sage graphs are actually NetworkX graphs, wrapped in a Sage class.82 In fact, any graph can produce its underlying NetworkX graph. For83 example,84 85 ::86 87 sage: import networkx88 sage: G = graphs.PetersenGraph()89 sage: N = G.networkx_graph()90 sage: isinstance(N, networkx.graph.Graph)91 True92 93 The NetworkX graph is essentially a dictionary of dictionaries of dictionaries::94 95 sage: N.adj96 {0: {1: {}, 4: {}, 5: {}}, 1: {0: {}, 2: {}, 6: {}}, 2: {1: {}, 3: {}, 7: {}}, 3: {8: {}, 2: {}, 4: {}}, 4: {0: {}, 9: {}, 3: {}}, 5: {0: {}, 8: {}, 7: {}}, 6: {8: {}, 1: {}, 9: {}}, 7: {9: {}, 2: {}, 5: {}}, 8: {3: {}, 5: {}, 6: {}}, 9: {4: {}, 6: {}, 7: {}}}97 98 Each dictionary key is a vertex label, and each key in the99 following dictionary is a neighbor of that vertex. In undirected100 graphs, there is redundancy: for example, the dictionary containing101 the entry ``1: {2: {}}`` implies it must contain102 ``{2: {1: {}}``. The innermost entry of ``{}`` is103 related to edge labeling (see section :ref:`Graph:labels`).104 105 78 Supported formats 106 79 ~~~~~~~~~~~~~~~~~ 107 80 … … 123 96 124 97 :: 125 98 99 sage: import networkx 126 100 sage: K = networkx.complete_bipartite_graph(12,7) 127 101 sage: G = Graph(K) 128 102 sage: G.degree() … … 460 434 461 435 INPUT: 462 436 463  ``data``  can be any of the following :437  ``data``  can be any of the following (see the ``format`` argument): 464 438 465 439 #. A dictionary of dictionaries 466 440 … … 470 444 471 445 #. A Sage adjacency matrix or incidence matrix 472 446 473 #. A pygraphviz agraph447 #. A pygraphviz graph 474 448 475 449 #. A SciPy sparse matrix 476 450 477 #. A NetworkX digraph451 #. A NetworkX graph 478 452 479 453  ``pos``  a positioning dictionary: for example, the 480 454 spring layout from NetworkX for the 5cycle is:: … … 523 497 iterable container of elliptic curves, and the graph produced has 524 498 each curve as a vertex (it's Cremona label) and an edge EF 525 499 labelled p if and only if E is congruent to F mod p 500 501  ``NX``  data must be a NetworkX Graph. 502 503 .. NOTE:: 504 505 As Sage's default edge labels is ``None`` while NetworkX uses 506 ``{}``, the ``{}`` labels of a NetworkX graph are automatically 507 set to ``None`` when it is converted to a Sage graph. This 508 behaviour can be overruled by setting the keyword 509 ``convert_empty_dict_labels_to_None`` to ``False`` (it is 510 ``True`` by default). 526 511 527 512  ``boundary``  a list of boundary vertices, if 528 513 empty, graph is considered as a 'graph without boundary' … … 960 945 format = 'NX' 961 946 962 947 # At this point, format has been set. 948 949 # adjust for empty dicts instead of None in NetworkX default edge labels 950 kwds.setdefault('convert_empty_dict_labels_to_None', (format == 'NX')) 963 951 964 952 verts = None 965 953 … … 1263 1251 self.add_edge(uu,vv) 1264 1252 1265 1253 elif format == 'dict_of_dicts': 1266 for u in data: 1267 for v in data[u]: 1268 if hash(u) <= hash(v) or v not in data or u not in data[v]: 1269 if multiedges: 1270 self.add_edges([(u,v,l) for l in data[u][v]]) 1271 else: 1272 self.add_edge((u,v,data[u][v])) 1254 if kwds.get('convert_empty_dict_labels_to_None', False): 1255 for u in data: 1256 for v in data[u]: 1257 if hash(u) <= hash(v) or v not in data or u not in data[v]: 1258 if multiedges: 1259 self.add_edges([(u,v,l) for l in data[u][v]]) 1260 else: 1261 self.add_edge((u,v,data[u][v] if data[u][v] != {} else None)) 1262 else: 1263 for u in data: 1264 for v in data[u]: 1265 if hash(u) <= hash(v) or v not in data or u not in data[v]: 1266 if multiedges: 1267 self.add_edges([(u,v,l) for l in data[u][v]]) 1268 else: 1269 self.add_edge((u,v,data[u][v])) 1273 1270 1274 1271 elif format == 'dict_of_lists': 1275 1272 for u in data: … … 1636 1633 1637 1634 sage: g=graphs.CycleGraph(5); 1638 1635 sage: g.eulerian_circuit() 1639 [(0, 1, {}), (1, 2, {}), (2, 3, {}), (3, 4, {}), (4, 0, {})]1636 [(0, 1, None), (1, 2, None), (2, 3, None), (3, 4, None), (4, 0, None)] 1640 1637 sage: g.eulerian_circuit(labels=False) 1641 1638 [(0, 1), (1, 2), (2, 3), (3, 4), (4, 0)] 1642 1639 sage: g = graphs.CompleteGraph(7)