@@ -17116,17 +17116,33 @@ def shortest_path_all_pairs(self, by_weight=False, algorithm=None,
17116
17116
sage: G.plot(edge_labels=True).show() # long time
17117
17117
sage: dist, pred = G.shortest_path_all_pairs(by_weight = True)
17118
17118
sage: dist
17119
- {0: {0: 0, 1: 1, 2: 2, 3: 3, 4: 2}, 1: {0: 1, 1: 0, 2: 1, 3: 2, 4: 3}, 2: {0: 2, 1: 1, 2: 0, 3: 1, 4: 3}, 3: {0: 3, 1: 2, 2: 1, 3: 0, 4: 2}, 4: {0: 2, 1: 3, 2: 3, 3: 2, 4: 0}}
17119
+ {0: {0: 0, 1: 1, 2: 2, 3: 3, 4: 2},
17120
+ 1: {0: 1, 1: 0, 2: 1, 3: 2, 4: 3},
17121
+ 2: {0: 2, 1: 1, 2: 0, 3: 1, 4: 3},
17122
+ 3: {0: 3, 1: 2, 2: 1, 3: 0, 4: 2},
17123
+ 4: {0: 2, 1: 3, 2: 3, 3: 2, 4: 0}}
17120
17124
sage: pred
17121
- {0: {0: None, 1: 0, 2: 1, 3: 2, 4: 0}, 1: {0: 1, 1: None, 2: 1, 3: 2, 4: 0}, 2: {0: 1, 1: 2, 2: None, 3: 2, 4: 3}, 3: {0: 1, 1: 2, 2: 3, 3: None, 4: 3}, 4: {0: 4, 1: 0, 2: 3, 3: 4, 4: None}}
17125
+ {0: {0: None, 1: 0, 2: 1, 3: 2, 4: 0},
17126
+ 1: {0: 1, 1: None, 2: 1, 3: 2, 4: 0},
17127
+ 2: {0: 1, 1: 2, 2: None, 3: 2, 4: 3},
17128
+ 3: {0: 1, 1: 2, 2: 3, 3: None, 4: 3},
17129
+ 4: {0: 4, 1: 0, 2: 3, 3: 4, 4: None}}
17122
17130
sage: pred[0]
17123
17131
{0: None, 1: 0, 2: 1, 3: 2, 4: 0}
17124
17132
sage: G = Graph( { 0: {1: {'weight':1}}, 1: {2: {'weight':1}}, 2: {3: {'weight':1}}, 3: {4: {'weight':2}}, 4: {0: {'weight':2}} }, sparse=True)
17125
17133
sage: dist, pred = G.shortest_path_all_pairs(weight_function = lambda e:e[2]['weight'])
17126
17134
sage: dist
17127
- {0: {0: 0, 1: 1, 2: 2, 3: 3, 4: 2}, 1: {0: 1, 1: 0, 2: 1, 3: 2, 4: 3}, 2: {0: 2, 1: 1, 2: 0, 3: 1, 4: 3}, 3: {0: 3, 1: 2, 2: 1, 3: 0, 4: 2}, 4: {0: 2, 1: 3, 2: 3, 3: 2, 4: 0}}
17135
+ {0: {0: 0, 1: 1, 2: 2, 3: 3, 4: 2},
17136
+ 1: {0: 1, 1: 0, 2: 1, 3: 2, 4: 3},
17137
+ 2: {0: 2, 1: 1, 2: 0, 3: 1, 4: 3},
17138
+ 3: {0: 3, 1: 2, 2: 1, 3: 0, 4: 2},
17139
+ 4: {0: 2, 1: 3, 2: 3, 3: 2, 4: 0}}
17128
17140
sage: pred
17129
- {0: {0: None, 1: 0, 2: 1, 3: 2, 4: 0}, 1: {0: 1, 1: None, 2: 1, 3: 2, 4: 0}, 2: {0: 1, 1: 2, 2: None, 3: 2, 4: 3}, 3: {0: 1, 1: 2, 2: 3, 3: None, 4: 3}, 4: {0: 4, 1: 0, 2: 3, 3: 4, 4: None}}
17141
+ {0: {0: None, 1: 0, 2: 1, 3: 2, 4: 0},
17142
+ 1: {0: 1, 1: None, 2: 1, 3: 2, 4: 0},
17143
+ 2: {0: 1, 1: 2, 2: None, 3: 2, 4: 3},
17144
+ 3: {0: 1, 1: 2, 2: 3, 3: None, 4: 3},
17145
+ 4: {0: 4, 1: 0, 2: 3, 3: 4, 4: None}}
17130
17146
17131
17147
So for example the shortest weighted path from `0` to `3` is obtained as
17132
17148
follows. The predecessor of `3` is ``pred[0][3] == 2``, the predecessor
@@ -17344,11 +17360,12 @@ def shortest_path_all_pairs(self, by_weight=False, algorithm=None,
17344
17360
return_predecessors=True, unweighted=not by_weight)
17345
17361
17346
17362
# and format the result
17347
- dist = {int_to_vertex[i]: {int_to_vertex[j]: dd[i, j] for j in range(n) if dd[i, j] != +Infinity}
17348
- for i in range(n)}
17363
+ dist = {int_to_vertex[i]: {int_to_vertex[j]: dd[i, j]
17364
+ for j in range(n) if dd[i, j] != +Infinity}
17365
+ for i in range(n)}
17349
17366
pred = {int_to_vertex[i]: {int_to_vertex[j]: (int_to_vertex[pp[i, j]] if i != j else None)
17350
- for j in range(n) if (i == j or pp[i, j] != -9999)}
17351
- for i in range(n)}
17367
+ for j in range(n) if (i == j or pp[i, j] != -9999)}
17368
+ for i in range(n)}
17352
17369
return dist, pred
17353
17370
17354
17371
elif algorithm == "Johnson_Boost":
@@ -17367,9 +17384,9 @@ def shortest_path_all_pairs(self, by_weight=False, algorithm=None,
17367
17384
dist = dict()
17368
17385
pred = dict()
17369
17386
for u in self:
17370
- paths= self.shortest_paths(u, by_weight=by_weight,
17371
- algorithm=algorithm,
17372
- weight_function=weight_function)
17387
+ paths = self.shortest_paths(u, by_weight=by_weight,
17388
+ algorithm=algorithm,
17389
+ weight_function=weight_function)
17373
17390
dist[u] = {v: self._path_length(p, by_weight=by_weight,
17374
17391
weight_function=weight_function)
17375
17392
for v, p in paths.items()}
@@ -17605,7 +17622,7 @@ def wiener_index(self, by_weight=False, algorithm=None,
17605
17622
G = networkx.Graph(list(self.edges(labels=False, sort=False)))
17606
17623
G.add_nodes_from(self)
17607
17624
total = sum(sum(networkx.single_source_dijkstra_path_length(G, u).values())
17608
- for u in G)
17625
+ for u in G)
17609
17626
WI = total if self.is_directed() else (total / 2)
17610
17627
17611
17628
else:
@@ -17687,14 +17704,14 @@ def average_distance(self, by_weight=False, algorithm=None,
17687
17704
"""
17688
17705
if self.order() < 2:
17689
17706
raise ValueError("average distance is not defined for empty or one-element graph")
17690
- WI = self.wiener_index(by_weight=by_weight, algorithm=algorithm,
17691
- weight_function=weight_function, check_weight=check_weight)
17707
+ WI = self.wiener_index(by_weight=by_weight, algorithm=algorithm,
17708
+ weight_function=weight_function, check_weight=check_weight)
17692
17709
f = 1 if self.is_directed() else 2
17693
17710
if WI in ZZ:
17694
17711
return QQ((f * WI, self.order() * (self.order() - 1)))
17695
17712
return f * WI / (self.order() * (self.order() - 1))
17696
17713
17697
- ### Searches
17714
+ # Searches
17698
17715
17699
17716
def breadth_first_search(self, start, ignore_direction=False,
17700
17717
distance=None, neighbors=None,
@@ -18038,7 +18055,7 @@ def depth_first_search(self, start, ignore_direction=False,
18038
18055
if x not in seen:
18039
18056
queue.append((w, x, d + 1))
18040
18057
18041
- ### Constructors
18058
+ # Constructors
18042
18059
18043
18060
def add_clique(self, vertices, loops=False):
18044
18061
"""
@@ -18543,7 +18560,9 @@ def cartesian_product(self, other):
18543
18560
sage: H = Graph([('a', 'b')])
18544
18561
sage: C1 = G.cartesian_product(H)
18545
18562
sage: C1.edges(sort=True, labels=None)
18546
- [((0, 'a'), (0, 'b')), ((0, 'a'), (1, 'a')), ((0, 'b'), (1, 'b')), ((1, 'a'), (1, 'b')), ((1, 'a'), (2, 'a')), ((1, 'b'), (2, 'b')), ((2, 'a'), (2, 'b'))]
18563
+ [((0, 'a'), (0, 'b')), ((0, 'a'), (1, 'a')), ((0, 'b'), (1, 'b')),
18564
+ ((1, 'a'), (1, 'b')), ((1, 'a'), (2, 'a')), ((1, 'b'), (2, 'b')),
18565
+ ((2, 'a'), (2, 'b'))]
18547
18566
sage: C2 = H.cartesian_product(G)
18548
18567
sage: C1.is_isomorphic(C2)
18549
18568
True
@@ -18562,7 +18581,16 @@ def cartesian_product(self, other):
18562
18581
sage: B = digraphs.DeBruijn(['a', 'b'], 2)
18563
18582
sage: Q = P.cartesian_product(B)
18564
18583
sage: Q.edges(sort=True, labels=None)
18565
- [((0, 'aa'), (0, 'aa')), ((0, 'aa'), (0, 'ab')), ((0, 'aa'), (1, 'aa')), ((0, 'ab'), (0, 'ba')), ((0, 'ab'), (0, 'bb')), ((0, 'ab'), (1, 'ab')), ((0, 'ba'), (0, 'aa')), ((0, 'ba'), (0, 'ab')), ((0, 'ba'), (1, 'ba')), ((0, 'bb'), (0, 'ba')), ((0, 'bb'), (0, 'bb')), ((0, 'bb'), (1, 'bb')), ((1, 'aa'), (1, 'aa')), ((1, 'aa'), (1, 'ab')), ((1, 'ab'), (1, 'ba')), ((1, 'ab'), (1, 'bb')), ((1, 'ba'), (1, 'aa')), ((1, 'ba'), (1, 'ab')), ((1, 'bb'), (1, 'ba')), ((1, 'bb'), (1, 'bb'))]
18584
+ [((0, 'aa'), (0, 'aa')), ((0, 'aa'), (0, 'ab')),
18585
+ ((0, 'aa'), (1, 'aa')), ((0, 'ab'), (0, 'ba')),
18586
+ ((0, 'ab'), (0, 'bb')), ((0, 'ab'), (1, 'ab')),
18587
+ ((0, 'ba'), (0, 'aa')), ((0, 'ba'), (0, 'ab')),
18588
+ ((0, 'ba'), (1, 'ba')), ((0, 'bb'), (0, 'ba')),
18589
+ ((0, 'bb'), (0, 'bb')), ((0, 'bb'), (1, 'bb')),
18590
+ ((1, 'aa'), (1, 'aa')), ((1, 'aa'), (1, 'ab')),
18591
+ ((1, 'ab'), (1, 'ba')), ((1, 'ab'), (1, 'bb')),
18592
+ ((1, 'ba'), (1, 'aa')), ((1, 'ba'), (1, 'ab')),
18593
+ ((1, 'bb'), (1, 'ba')), ((1, 'bb'), (1, 'bb'))]
18566
18594
sage: Q.strongly_connected_components_digraph().num_verts()
18567
18595
2
18568
18596
sage: V = Q.strongly_connected_component_containing_vertex((0, 'aa'))
@@ -18709,7 +18737,10 @@ def lexicographic_product(self, other):
18709
18737
sage: H = Graph([('a', 'b')])
18710
18738
sage: T = G.lexicographic_product(H)
18711
18739
sage: T.edges(sort=True, labels=None)
18712
- [((0, 'a'), (0, 'b')), ((0, 'a'), (1, 'a')), ((0, 'a'), (1, 'b')), ((0, 'b'), (1, 'a')), ((0, 'b'), (1, 'b')), ((1, 'a'), (1, 'b')), ((1, 'a'), (2, 'a')), ((1, 'a'), (2, 'b')), ((1, 'b'), (2, 'a')), ((1, 'b'), (2, 'b')), ((2, 'a'), (2, 'b'))]
18740
+ [((0, 'a'), (0, 'b')), ((0, 'a'), (1, 'a')), ((0, 'a'), (1, 'b')),
18741
+ ((0, 'b'), (1, 'a')), ((0, 'b'), (1, 'b')), ((1, 'a'), (1, 'b')),
18742
+ ((1, 'a'), (2, 'a')), ((1, 'a'), (2, 'b')), ((1, 'b'), (2, 'a')),
18743
+ ((1, 'b'), (2, 'b')), ((2, 'a'), (2, 'b'))]
18713
18744
sage: T.is_isomorphic(H.lexicographic_product(G))
18714
18745
False
18715
18746
@@ -18719,7 +18750,10 @@ def lexicographic_product(self, other):
18719
18750
sage: J = DiGraph([('a', 'b')])
18720
18751
sage: T = I.lexicographic_product(J)
18721
18752
sage: T.edges(sort=True, labels=None)
18722
- [((0, 'a'), (0, 'b')), ((0, 'a'), (1, 'a')), ((0, 'a'), (1, 'b')), ((0, 'b'), (1, 'a')), ((0, 'b'), (1, 'b')), ((1, 'a'), (1, 'b')), ((1, 'a'), (2, 'a')), ((1, 'a'), (2, 'b')), ((1, 'b'), (2, 'a')), ((1, 'b'), (2, 'b')), ((2, 'a'), (2, 'b'))]
18753
+ [((0, 'a'), (0, 'b')), ((0, 'a'), (1, 'a')), ((0, 'a'), (1, 'b')),
18754
+ ((0, 'b'), (1, 'a')), ((0, 'b'), (1, 'b')), ((1, 'a'), (1, 'b')),
18755
+ ((1, 'a'), (2, 'a')), ((1, 'a'), (2, 'b')), ((1, 'b'), (2, 'a')),
18756
+ ((1, 'b'), (2, 'b')), ((2, 'a'), (2, 'b'))]
18723
18757
sage: T.is_isomorphic(J.lexicographic_product(I))
18724
18758
False
18725
18759
"""
@@ -18861,7 +18895,11 @@ def disjunctive_product(self, other):
18861
18895
sage: H = Graph([('a', 'b')])
18862
18896
sage: T = G.disjunctive_product(H)
18863
18897
sage: T.edges(sort=True, labels=None)
18864
- [((0, 'a'), (0, 'b')), ((0, 'a'), (1, 'a')), ((0, 'a'), (1, 'b')), ((0, 'a'), (2, 'b')), ((0, 'b'), (1, 'a')), ((0, 'b'), (1, 'b')), ((0, 'b'), (2, 'a')), ((1, 'a'), (1, 'b')), ((1, 'a'), (2, 'a')), ((1, 'a'), (2, 'b')), ((1, 'b'), (2, 'a')), ((1, 'b'), (2, 'b')), ((2, 'a'), (2, 'b'))]
18898
+ [((0, 'a'), (0, 'b')), ((0, 'a'), (1, 'a')), ((0, 'a'), (1, 'b')),
18899
+ ((0, 'a'), (2, 'b')), ((0, 'b'), (1, 'a')), ((0, 'b'), (1, 'b')),
18900
+ ((0, 'b'), (2, 'a')), ((1, 'a'), (1, 'b')), ((1, 'a'), (2, 'a')),
18901
+ ((1, 'a'), (2, 'b')), ((1, 'b'), (2, 'a')), ((1, 'b'), (2, 'b')),
18902
+ ((2, 'a'), (2, 'b'))]
18865
18903
sage: T.is_isomorphic(H.disjunctive_product(G))
18866
18904
True
18867
18905
@@ -18871,7 +18909,11 @@ def disjunctive_product(self, other):
18871
18909
sage: J = DiGraph([('a', 'b')])
18872
18910
sage: T = I.disjunctive_product(J)
18873
18911
sage: T.edges(sort=True, labels=None)
18874
- [((0, 'a'), (0, 'b')), ((0, 'a'), (1, 'a')), ((0, 'a'), (1, 'b')), ((0, 'a'), (2, 'b')), ((0, 'b'), (1, 'a')), ((0, 'b'), (1, 'b')), ((1, 'a'), (0, 'b')), ((1, 'a'), (1, 'b')), ((1, 'a'), (2, 'a')), ((1, 'a'), (2, 'b')), ((1, 'b'), (2, 'a')), ((1, 'b'), (2, 'b')), ((2, 'a'), (0, 'b')), ((2, 'a'), (1, 'b')), ((2, 'a'), (2, 'b'))]
18912
+ [((0, 'a'), (0, 'b')), ((0, 'a'), (1, 'a')), ((0, 'a'), (1, 'b')),
18913
+ ((0, 'a'), (2, 'b')), ((0, 'b'), (1, 'a')), ((0, 'b'), (1, 'b')),
18914
+ ((1, 'a'), (0, 'b')), ((1, 'a'), (1, 'b')), ((1, 'a'), (2, 'a')),
18915
+ ((1, 'a'), (2, 'b')), ((1, 'b'), (2, 'a')), ((1, 'b'), (2, 'b')),
18916
+ ((2, 'a'), (0, 'b')), ((2, 'a'), (1, 'b')), ((2, 'a'), (2, 'b'))]
18875
18917
sage: T.is_isomorphic(J.disjunctive_product(I))
18876
18918
True
18877
18919
"""
@@ -19047,8 +19089,7 @@ def is_transitively_reduced(self):
19047
19089
19048
19090
return self.is_forest()
19049
19091
19050
-
19051
- ### Visualization
19092
+ # Visualization
19052
19093
19053
19094
def _color_by_label(self, format='hex', as_function=False, default_color="black"):
19054
19095
"""
@@ -19149,7 +19190,8 @@ def _color_by_label(self, format='hex', as_function=False, default_color="black"
19149
19190
color_of_label = dict(zip(labels, colors))
19150
19191
color_of_label = color_of_label.__getitem__
19151
19192
elif isinstance(format, dict):
19152
- color_of_label = lambda label: format.get(label, default_color)
19193
+ def color_of_label(label):
19194
+ return format.get(label, default_color)
19153
19195
else:
19154
19196
# This assumes that ``format`` is already a function
19155
19197
color_of_label = format
@@ -19218,7 +19260,6 @@ def set_latex_options(self, **kwds):
19218
19260
opts = self.latex_options()
19219
19261
opts.set_options(**kwds)
19220
19262
19221
-
19222
19263
def layout(self, layout=None, pos=None, dim=2, save_pos=False, **options):
19223
19264
"""
19224
19265
Return a layout for the vertices of this graph.
@@ -19341,10 +19382,10 @@ def layout(self, layout=None, pos=None, dim=2, save_pos=False, **options):
19341
19382
if pos is None:
19342
19383
layout = 'default'
19343
19384
19344
- if hasattr(self, "layout_%s"% layout):
19345
- pos = getattr(self, "layout_%s"% layout)(dim=dim, **options)
19385
+ if hasattr(self, "layout_%s" % layout):
19386
+ pos = getattr(self, "layout_%s" % layout)(dim=dim, **options)
19346
19387
elif layout is not None:
19347
- raise ValueError("unknown layout algorithm: %s"% layout)
19388
+ raise ValueError("unknown layout algorithm: %s" % layout)
19348
19389
19349
19390
if len(pos) < self.order():
19350
19391
pos = self.layout_extend_randomly(pos, dim=dim)
@@ -19353,7 +19394,6 @@ def layout(self, layout=None, pos=None, dim=2, save_pos=False, **options):
19353
19394
self.set_pos(pos, dim=dim)
19354
19395
return pos
19355
19396
19356
-
19357
19397
def layout_spring(self, by_component=True, **options):
19358
19398
"""
19359
19399
Return a spring layout for this graph.
@@ -19490,11 +19530,11 @@ def layout_extend_randomly(self, pos, dim=2):
19490
19530
sage: (xmin, ymin) == (0, 0) and (xmax, ymax) == (1, 1)
19491
19531
True
19492
19532
"""
19493
- assert dim == 2 # 3d not yet implemented
19533
+ assert dim == 2 # 3d not yet implemented
19494
19534
from sage.misc.randstate import current_randstate
19495
19535
random = current_randstate().python_random().random
19496
19536
19497
- xmin, xmax,ymin, ymax = self._layout_bounding_box(pos)
19537
+ xmin, xmax, ymin, ymax = self._layout_bounding_box(pos)
19498
19538
19499
19539
dx = xmax - xmin
19500
19540
dy = ymax - ymin
@@ -19505,7 +19545,6 @@ def layout_extend_randomly(self, pos, dim=2):
19505
19545
pos[v] = [xmin + dx * random(), ymin + dy * random()]
19506
19546
return pos
19507
19547
19508
-
19509
19548
def layout_circular(self, dim=2, center=(0, 0), radius=1, shift=0, angle=0, **options):
19510
19549
r"""
19511
19550
Return a circular layout for this graph
@@ -19947,9 +19986,9 @@ def _layout_bounding_box(self, pos):
19947
19986
ys = [pos[v][1] for v in pos]
19948
19987
if not xs:
19949
19988
xmin = -1
19950
- xmax = 1
19989
+ xmax = 1
19951
19990
ymin = -1
19952
- ymax = 1
19991
+ ymax = 1
19953
19992
else:
19954
19993
xmin = min(xs)
19955
19994
xmax = max(xs)
@@ -20047,7 +20086,7 @@ def _circle_embedding(self, vertices, center=(0, 0), radius=1, shift=0, angle=0,
20047
20086
pos = self._pos = {}
20048
20087
20049
20088
from math import sin, cos, pi
20050
- for i,v in enumerate(vertices):
20089
+ for i, v in enumerate(vertices):
20051
20090
i += shift
20052
20091
# We round cos and sin to avoid results like 1.2246467991473532e-16
20053
20092
# when asking for sin(pi)
@@ -20365,7 +20404,11 @@ def plot(self, **options):
20365
20404
20366
20405
::
20367
20406
20368
- sage: D = DiGraph( { 0: [1, 10, 19], 1: [8, 2], 2: [3, 6], 3: [19, 4], 4: [17, 5], 5: [6, 15], 6: [7], 7: [8, 14], 8: [9], 9: [10, 13], 10: [11], 11: [12, 18], 12: [16, 13], 13: [14], 14: [15], 15: [16], 16: [17], 17: [18], 18: [19], 19: []} , sparse=True)
20407
+ sage: D = DiGraph({0: [1, 10, 19], 1: [8, 2], 2: [3, 6], 3: [19, 4],
20408
+ ....: 4: [17, 5], 5: [6, 15], 6: [7], 7: [8, 14],
20409
+ ....: 8: [9], 9: [10, 13], 10: [11], 11: [12, 18],
20410
+ ....: 12: [16, 13], 13: [14], 14: [15], 15: [16],
20411
+ ....: 16: [17], 17: [18], 18: [19]}, sparse=True)
20369
20412
sage: for u,v,l in D.edges(sort=False):
20370
20413
....: D.set_edge_label(u, v, '(' + str(u) + ',' + str(v) + ')')
20371
20414
sage: D.plot(edge_labels=True, layout='circular').show()
@@ -20559,7 +20602,7 @@ def show(self, method="matplotlib", **kwds):
20559
20602
return
20560
20603
from sage.misc.viewer import browser
20561
20604
import os
20562
- os.system('%s %s 2>/dev/null 1>/dev/null &'% (browser(), filename))
20605
+ os.system('%s %s 2>/dev/null 1>/dev/null &' % (browser(), filename))
20563
20606
return
20564
20607
20565
20608
from .graph_plot import graphplot_options
0 commit comments