@@ -4704,17 +4704,23 @@ def min_spanning_tree(self,
4704
4704
sage: len(g.min_spanning_tree())
4705
4705
4
4706
4706
sage: weight = lambda e: 1 / ((e[0] + 1) * (e[1] + 1))
4707
- sage: sorted(g.min_spanning_tree(weight_function=weight))
4708
- [(0, 4, None), (1, 4, None), (2, 4, None), (3, 4, None)]
4709
- sage: sorted(g.min_spanning_tree(weight_function=weight,
4710
- ....: algorithm='Kruskal_Boost'))
4711
- [(0, 4, None), (1, 4, None), (2, 4, None), (3, 4, None)]
4707
+ sage: E = g.min_spanning_tree(weight_function=weight)
4708
+ sage: T = Graph(E)
4709
+ sage: set(g) == set(T) and T.order() == T.size() + 1 and T.is_tree()
4710
+ True
4711
+ sage: sum(map(weight, E))
4712
+ 5/12
4713
+ sage: E = g.min_spanning_tree(weight_function=weight,
4714
+ ....: algorithm='Kruskal_Boost')
4715
+ sage: Graph(E).is_tree(); sum(map(weight, E))
4716
+ True
4717
+ 5/12
4712
4718
sage: g = graphs.PetersenGraph()
4713
4719
sage: g.allow_multiple_edges(True)
4714
4720
sage: g.add_edges(g.edge_iterator())
4715
- sage: sorted (g.min_spanning_tree())
4716
- [(0, 1, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 6, None),
4717
- (3, 8, None), (5, 7, None), (5, 8, None), (6, 9, None)]
4721
+ sage: T = Graph (g.min_spanning_tree())
4722
+ sage: set(g) == set(T) and T.order() == T.size() + 1 and T.is_tree()
4723
+ True
4718
4724
4719
4725
Boruvka's algorithm::
4720
4726
@@ -4725,15 +4731,13 @@ def min_spanning_tree(self,
4725
4731
Prim's algorithm::
4726
4732
4727
4733
sage: g = graphs.CompleteGraph(5)
4728
- sage: sorted(g.min_spanning_tree(algorithm='Prim_edge',
4729
- ....: starting_vertex=2, weight_function=weight))
4730
- [(0, 4, None), (1, 4, None), (2, 4, None), (3, 4, None)]
4731
- sage: sorted(g.min_spanning_tree(algorithm='Prim_fringe',
4732
- ....: starting_vertex=2, weight_function=weight))
4733
- [(0, 4, None), (1, 4, None), (2, 4, None), (3, 4, None)]
4734
- sage: sorted(g.min_spanning_tree(weight_function=weight,
4735
- ....: algorithm='Prim_Boost'))
4736
- [(0, 4, None), (1, 4, None), (2, 4, None), (3, 4, None)]
4734
+ sage: for algo in ['Prim_edge', 'Prim_fringe', 'Prim_Boost']:
4735
+ ....: E = g.min_spanning_tree(algorithm=algo, weight_function=weight)
4736
+ ....: T = Graph(E)
4737
+ ....: print(set(g) == set(T) and T.order() == T.size() + 1 and T.is_tree())
4738
+ True
4739
+ True
4740
+ True
4737
4741
4738
4742
NetworkX algorithm::
4739
4743
@@ -4745,82 +4749,93 @@ def min_spanning_tree(self,
4745
4749
sage: G = Graph([(0, 1, {'name': 'a', 'weight': 1}),
4746
4750
....: (0, 2, {'name': 'b', 'weight': 3}),
4747
4751
....: (1, 2, {'name': 'b', 'weight': 1})])
4748
- sage: sorted(G.min_spanning_tree(weight_function=lambda e: e[2]['weight']))
4752
+ sage: sorted(G.min_spanning_tree(algorithm='Boruvka',
4753
+ ....: weight_function=lambda e: e[2]['weight']))
4749
4754
[(0, 1, {'name': 'a', 'weight': 1}), (1, 2, {'name': 'b', 'weight': 1})]
4750
4755
4751
4756
If the graph is not weighted, edge labels are not considered, even if
4752
4757
they are numbers::
4753
4758
4754
4759
sage: g = Graph([(1, 2, 1), (1, 3, 2), (2, 3, 1)])
4755
- sage: sorted(g.min_spanning_tree())
4760
+ sage: sorted(g.min_spanning_tree(algorithm='Boruvka' ))
4756
4761
[(1, 2, 1), (1, 3, 2)]
4757
4762
4758
4763
In order to use weights, we need either to set variable ``weighted`` to
4759
4764
``True``, or to specify a weight function or set by_weight to ``True``::
4760
4765
4761
4766
sage: g.weighted(True)
4762
- sage: sorted (g.min_spanning_tree())
4767
+ sage: Graph (g.min_spanning_tree()).edges(sort=True )
4763
4768
[(1, 2, 1), (2, 3, 1)]
4764
4769
sage: g.weighted(False)
4765
- sage: sorted (g.min_spanning_tree())
4770
+ sage: Graph (g.min_spanning_tree()).edges(sort=True )
4766
4771
[(1, 2, 1), (1, 3, 2)]
4767
- sage: sorted(g.min_spanning_tree(by_weight=True))
4772
+ sage: Graph(g.min_spanning_tree(by_weight=True)).edges(sort=True)
4773
+ [(1, 2, 1), (2, 3, 1)]
4774
+ sage: Graph(g.min_spanning_tree(weight_function=lambda e: e[2])).edges(sort=True)
4768
4775
[(1, 2, 1), (2, 3, 1)]
4769
- sage: sorted(g.min_spanning_tree(weight_function=lambda e: e[2]))
4776
+
4777
+ Note that the order of the vertices on each edge is not guaranteed and
4778
+ may differ from an algorithm to the other::
4779
+
4780
+ sage: g.weighted(True)
4781
+ sage: sorted(g.min_spanning_tree())
4782
+ [(2, 1, 1), (3, 2, 1)]
4783
+ sage: sorted(g.min_spanning_tree(algorithm='Boruvka'))
4784
+ [(1, 2, 1), (2, 3, 1)]
4785
+ sage: Graph(g.min_spanning_tree()).edges(sort=True)
4770
4786
[(1, 2, 1), (2, 3, 1)]
4771
4787
4788
+
4772
4789
TESTS:
4773
4790
4774
4791
Check that, if ``weight_function`` is not provided, then edge weights
4775
4792
are used::
4776
4793
4777
4794
sage: g = Graph(weighted=True)
4778
4795
sage: g.add_edges([[0, 1, 1], [1, 2, 1], [2, 0, 10]])
4779
- sage: sorted (g.min_spanning_tree())
4796
+ sage: Graph (g.min_spanning_tree()).edges(sort=True )
4780
4797
[(0, 1, 1), (1, 2, 1)]
4781
- sage: sorted (g.min_spanning_tree(algorithm='Filter_Kruskal'))
4798
+ sage: Graph (g.min_spanning_tree(algorithm='Filter_Kruskal')).edges(sort=True )
4782
4799
[(0, 1, 1), (1, 2, 1)]
4783
- sage: sorted (g.min_spanning_tree(algorithm='Kruskal_Boost'))
4800
+ sage: Graph (g.min_spanning_tree(algorithm='Kruskal_Boost')).edges(sort=True )
4784
4801
[(0, 1, 1), (1, 2, 1)]
4785
- sage: sorted (g.min_spanning_tree(algorithm='Prim_fringe'))
4802
+ sage: Graph (g.min_spanning_tree(algorithm='Prim_fringe')).edges(sort=True )
4786
4803
[(0, 1, 1), (1, 2, 1)]
4787
- sage: sorted (g.min_spanning_tree(algorithm='Prim_edge'))
4804
+ sage: Graph (g.min_spanning_tree(algorithm='Prim_edge')).edges(sort=True )
4788
4805
[(0, 1, 1), (1, 2, 1)]
4789
- sage: sorted (g.min_spanning_tree(algorithm='Prim_Boost'))
4806
+ sage: Graph (g.min_spanning_tree(algorithm='Prim_Boost')).edges(sort=True )
4790
4807
[(0, 1, 1), (1, 2, 1)]
4791
- sage: sorted (g.min_spanning_tree(algorithm='NetworkX ')) # needs networkx
4808
+ sage: Graph (g.min_spanning_tree(algorithm='Boruvka ')).edges(sort=True)
4792
4809
[(0, 1, 1), (1, 2, 1)]
4793
- sage: sorted (g.min_spanning_tree(algorithm='Boruvka '))
4810
+ sage: Graph (g.min_spanning_tree(algorithm='NetworkX ')).edges(sort=True) # needs networkx
4794
4811
[(0, 1, 1), (1, 2, 1)]
4795
4812
4796
4813
Check that, if ``weight_function`` is provided, it overrides edge
4797
4814
weights::
4798
4815
4799
4816
sage: g = Graph([[0, 1, 1], [1, 2, 1], [2, 0, 10]], weighted=True)
4800
4817
sage: weight = lambda e: 3 - e[0] - e[1]
4801
- sage: sorted (g.min_spanning_tree(weight_function=weight))
4818
+ sage: Graph (g.min_spanning_tree(weight_function=weight)).edges(sort=True )
4802
4819
[(0, 2, 10), (1, 2, 1)]
4803
- sage: sorted (g.min_spanning_tree(algorithm='Filter_Kruskal', weight_function=weight))
4820
+ sage: Graph (g.min_spanning_tree(algorithm='Filter_Kruskal', weight_function=weight)).edges(sort=True )
4804
4821
[(0, 2, 10), (1, 2, 1)]
4805
- sage: sorted (g.min_spanning_tree(algorithm='Kruskal_Boost', weight_function=weight))
4822
+ sage: Graph (g.min_spanning_tree(algorithm='Kruskal_Boost', weight_function=weight)).edges(sort=True )
4806
4823
[(0, 2, 10), (1, 2, 1)]
4807
- sage: sorted (g.min_spanning_tree(algorithm='Prim_fringe', weight_function=weight))
4824
+ sage: Graph (g.min_spanning_tree(algorithm='Prim_fringe', weight_function=weight)).edges(sort=True )
4808
4825
[(0, 2, 10), (1, 2, 1)]
4809
- sage: sorted (g.min_spanning_tree(algorithm='Prim_edge', weight_function=weight))
4826
+ sage: Graph (g.min_spanning_tree(algorithm='Prim_edge', weight_function=weight)).edges(sort=True )
4810
4827
[(0, 2, 10), (1, 2, 1)]
4811
- sage: sorted (g.min_spanning_tree(algorithm='Prim_Boost', weight_function=weight))
4828
+ sage: Graph (g.min_spanning_tree(algorithm='Prim_Boost', weight_function=weight)).edges(sort=True )
4812
4829
[(0, 2, 10), (1, 2, 1)]
4813
- sage: sorted(g.min_spanning_tree(algorithm='NetworkX', weight_function=weight)) # needs networkx
4814
- [(0, 2, 10), (1, 2, 1)]
4815
- sage: sorted(g.min_spanning_tree(algorithm='Boruvka', weight_function=weight))
4830
+ sage: Graph(g.min_spanning_tree(algorithm='NetworkX', weight_function=weight)).edges(sort=True) # needs networkx
4816
4831
[(0, 2, 10), (1, 2, 1)]
4817
4832
4818
4833
If the graph is directed, it is transformed into an undirected graph::
4819
4834
4820
4835
sage: g = digraphs.Circuit(3)
4821
- sage: sorted (g.min_spanning_tree(weight_function=weight))
4836
+ sage: Graph (g.min_spanning_tree(weight_function=weight)).edges(sort=True )
4822
4837
[(0, 2, None), (1, 2, None)]
4823
- sage: sorted (g.to_undirected().min_spanning_tree(weight_function=weight))
4838
+ sage: Graph (g.to_undirected().min_spanning_tree(weight_function=weight)).edges(sort=True )
4824
4839
[(0, 2, None), (1, 2, None)]
4825
4840
4826
4841
If at least an edge weight is not convertible to a float, an error is
@@ -4841,6 +4856,17 @@ def min_spanning_tree(self,
4841
4856
4842
4857
sage: graphs.EmptyGraph().min_spanning_tree()
4843
4858
[]
4859
+
4860
+ Check that the method is robust to incomparable vertices::
4861
+
4862
+ sage: G = Graph([(1, 2, 10), (1, 'a', 1), ('a', 'b', 1), ('b', 2, 1)])
4863
+ sage: E = G.min_spanning_tree(algorithm='Prim_Boost', by_weight=True)
4864
+ sage: E = G.min_spanning_tree(algorithm='Prim_fringe', by_weight=True)
4865
+ sage: E = G.min_spanning_tree(algorithm='Prim_edge', by_weight=True)
4866
+ sage: E = G.min_spanning_tree(algorithm='Kruskal_Boost', by_weight=True)
4867
+ sage: E = G.min_spanning_tree(algorithm='Filter_Kruskal', by_weight=True)
4868
+ sage: E = G.min_spanning_tree(algorithm='Boruvka', by_weight=True)
4869
+ sage: E = G.min_spanning_tree(algorithm='NetworkX', by_weight=True) # needs networkx
4844
4870
"""
4845
4871
if not self.order():
4846
4872
return []
@@ -5136,9 +5162,9 @@ def cycle_basis(self, output='vertex'):
5136
5162
sage: [sorted(c) for c in G.cycle_basis()] # needs networkx
5137
5163
[['Hey', 'Really ?', 'Wuuhuu'], [0, 2], [0, 1, 2]]
5138
5164
sage: [sorted(c) for c in G.cycle_basis(output='edge')] # needs networkx
5139
- [[('Hey', 'Wuuhuu ', None),
5140
- ('Really ?', 'Hey ', None),
5141
- ('Wuuhuu', 'Really ? ', None)],
5165
+ [[('Hey', 'Really ? ', None),
5166
+ ('Really ?', 'Wuuhuu ', None),
5167
+ ('Wuuhuu', 'Hey ', None)],
5142
5168
[(0, 2, 'a'), (2, 0, 'b')],
5143
5169
[(0, 2, 'b'), (1, 0, 'c'), (2, 1, 'd')]]
5144
5170
0 commit comments