Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 58 additions & 55 deletions src/sage/graphs/generic_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -972,10 +972,10 @@ def _latex_(self):
return self.latex_options().latex()

def tikz(self, format=None, edge_labels=None,
color_by_label=False, prog='dot', rankdir='down',
standalone_config=None, usepackage=None,
usetikzlibrary=None, macros=None,
use_sage_preamble=None, **kwds):
color_by_label=False, prog='dot', rankdir='down',
standalone_config=None, usepackage=None,
usetikzlibrary=None, macros=None,
use_sage_preamble=None, **kwds):
r"""
Return a TikzPicture of the graph.

Expand Down Expand Up @@ -1133,8 +1133,9 @@ def tikz(self, format=None, edge_labels=None,
edge_labels = True

self.latex_options().set_options(format=format,
edge_labels=edge_labels, color_by_label=color_by_label,
prog=prog, rankdir=rankdir, **kwds)
edge_labels=edge_labels,
color_by_label=color_by_label,
prog=prog, rankdir=rankdir, **kwds)

# by default use sage preamble only for format tkz_graph
# because content generated by tkz_graph depends on it
Expand Down Expand Up @@ -1216,7 +1217,7 @@ def _repr_(self):
name = self.name() + ": " + name
return name

def is_immutable(self):
def is_immutable(self) -> bool:
"""
Check whether the graph is immutable.

Expand Down Expand Up @@ -1659,14 +1660,14 @@ def export_to_file(self, filename, format=None, **kwds):
"""
import networkx

formats = {"adjlist" : networkx.write_adjlist,
"dot" : networkx.drawing.nx_pydot.write_dot,
"edgelist" : networkx.write_edgelist,
"gexf" : networkx.write_gexf,
"gml" : networkx.write_gml,
"graphml" : networkx.write_graphml,
"multiline_adjlist" : networkx.write_multiline_adjlist,
"pajek" : networkx.write_pajek}
formats = {"adjlist": networkx.write_adjlist,
"dot": networkx.drawing.nx_pydot.write_dot,
"edgelist": networkx.write_edgelist,
"gexf": networkx.write_gexf,
"gml": networkx.write_gml,
"graphml": networkx.write_graphml,
"multiline_adjlist": networkx.write_multiline_adjlist,
"pajek": networkx.write_pajek}

if format is None:
ext = filename[1 + filename.rfind("."):]
Expand Down Expand Up @@ -3498,7 +3499,7 @@ def connected(u, v):
"the list associated with {}".format(u, v, u, v))
return True

def has_loops(self):
def has_loops(self) -> bool:
"""
Return whether there are loops in the (di)graph.

Expand Down Expand Up @@ -3542,7 +3543,7 @@ def has_loops(self):
"""
return self.allows_loops() and any(self.has_edge(v, v) for v in self)

def allows_loops(self):
def allows_loops(self) -> bool:
"""
Return whether loops are permitted in the (di)graph.

Expand Down Expand Up @@ -3586,7 +3587,7 @@ def allows_loops(self):
"""
return self._backend.loops(None)

def allow_loops(self, new, check=True):
def allow_loops(self, new, check=True) -> None:
"""
Change whether loops are permitted in the (di)graph.

Expand Down Expand Up @@ -3748,7 +3749,7 @@ def number_of_loops(self):
"""
return len(self.loop_edges())

def loop_vertices(self):
def loop_vertices(self) -> list:
"""
Return a list of vertices with loops.

Expand All @@ -3762,7 +3763,7 @@ def loop_vertices(self):
return [v for v in self if self.has_edge(v, v)]
return []

def has_multiple_edges(self, to_undirected=False):
def has_multiple_edges(self, to_undirected=False) -> bool:
"""
Return whether there are multiple edges in the (di)graph.

Expand Down Expand Up @@ -3854,7 +3855,7 @@ def has_multiple_edges(self, to_undirected=False):
s.add(a)
return False

def allows_multiple_edges(self):
def allows_multiple_edges(self) -> bool:
"""
Return whether multiple edges are permitted in the (di)graph.

Expand Down Expand Up @@ -4221,7 +4222,7 @@ def name(self, new=None):

self._name = str(new)

def get_pos(self, dim=2):
def get_pos(self, dim=2) -> dict:
"""
Return the position dictionary.

Expand Down Expand Up @@ -6004,7 +6005,7 @@ def is_planar(self, on_embedding=None, kuratowski=False, set_embedding=False,
if self.has_multiple_edges() or self.has_loops():
raise NotImplementedError("cannot compute with embeddings of multiple-edged or looped graphs")
elif (self.is_directed() and
any(self.has_edge(v, u) for u, v in self.edge_iterator(labels=False))):
any(self.has_edge(v, u) for u, v in self.edge_iterator(labels=False))):
raise NotImplementedError("cannot compute with embeddings of digraphs with pairs of opposite arcs")

if on_embedding is not None:
Expand Down Expand Up @@ -6488,15 +6489,15 @@ def layout_planar(self, set_embedding=False, on_embedding=None,
_compute_coordinates(G, tree_nodes)

# Delete all the edges added to the graph
#G.delete_edges( extra_edges )
#self.delete_edges( other_added_edges )
# G.delete_edges( extra_edges )
# self.delete_edges( other_added_edges )

if embedding_copy is not None:
self._embedding = embedding_copy

return G._pos

def is_drawn_free_of_edge_crossings(self):
def is_drawn_free_of_edge_crossings(self) -> bool:
"""
Check whether the position dictionary for this graph is set and that
position dictionary gives a planar embedding.
Expand Down Expand Up @@ -8944,13 +8945,13 @@ def longest_path(self, s=None, t=None, use_edge_labels=False,
# the two in a directed graph (the graph is connected).
if (self.order() <= 1 or
(s is not None and (
(s not in self) or
(self._directed and not self.out_degree(s)) or
(not self._directed and not self.degree(s)))) or
(s not in self) or
(self._directed and not self.out_degree(s)) or
(not self._directed and not self.degree(s)))) or
(t is not None and (
(t not in self) or
(self._directed and not self.in_degree(t)) or
(not self._directed and not self.degree(t)))) or
(t not in self) or
(self._directed and not self.in_degree(t)) or
(not self._directed and not self.degree(t)))) or
(self._directed and (s is not None) and (t is not None) and
not self.shortest_path(s, t))):
if self._directed:
Expand Down Expand Up @@ -9658,7 +9659,7 @@ def weight(label):
(vv, uu, self.edge_label(vv, uu))]
answer = self.subgraph(edges=edges, immutable=self.is_immutable())
answer.set_pos(self.get_pos())
answer._name = "TSP from "+self.name()
answer._name = "TSP from " + self.name()
return answer
elif self.allows_multiple_edges() and len(self.edge_label(uu, vv)) > 1:
if maximize:
Expand Down Expand Up @@ -11818,7 +11819,7 @@ def delete_vertices(self, vertices):

self._backend.del_vertices(vertices)

def has_vertex(self, vertex):
def has_vertex(self, vertex) -> bool:
"""
Check if ``vertex`` is one of the vertices of this graph.

Expand Down Expand Up @@ -13326,7 +13327,7 @@ def set_edge_label(self, u, v, l):
"multiple edges from %s to %s" % (u, v))
self._backend.set_edge_label(u, v, l, self._directed)

def has_edge(self, u, v=None, label=None):
def has_edge(self, u, v=None, label=None) -> bool:
r"""
Check whether ``(u, v)`` is an edge of the (di)graph.

Expand Down Expand Up @@ -15292,7 +15293,7 @@ def subgraph_decompositions(self, H, induced=False):
from sage.combinat.matrices.dancing_links import dlx_solver

edges = list(self.edges(labels=False))
edge_to_column_id = {edge:i for i, edge in enumerate(edges)}
edge_to_column_id = {edge: i for i, edge in enumerate(edges)}

rows = set()
for h in self.subgraph_search_iterator(H, induced=induced, return_graphs=True):
Expand Down Expand Up @@ -19427,9 +19428,9 @@ def breadth_first_search(self, start, ignore_direction=False,
if (neighbors is None and not isinstance(start, list) and distance is None
and hasattr(self._backend, "breadth_first_search")):
yield from self._backend.breadth_first_search(
start, ignore_direction=ignore_direction,
report_distance=report_distance, edges=edges,
forbidden_vertices=forbidden_vertices)
start, ignore_direction=ignore_direction,
report_distance=report_distance, edges=edges,
forbidden_vertices=forbidden_vertices)
else:
if neighbors is None:
if not self._directed or ignore_direction:
Expand Down Expand Up @@ -22000,7 +22001,7 @@ def layout_tutte(self, external_face=None, external_face_pos=None, **options):
M[i, j] = -1
M[i, i] = len(nv)

sol = M.pseudoinverse()*b
sol = M.pseudoinverse() * b
return dict(zip(self, sol))

def _layout_bounding_box(self, pos):
Expand Down Expand Up @@ -22125,11 +22126,11 @@ def _circle_embedding(self, vertices, center=(0, 0), radius=1, shift=0, angle=0,

from math import cos, pi, sin
for i, v in enumerate(vertices):
i += shift
theta = angle + 2 * (i + shift) * pi / n
# We round cos and sin to avoid results like 1.2246467991473532e-16
# when asking for sin(pi)
v_x = c_x + radius * round(cos(angle + 2*i*pi / n), 10)
v_y = c_y + radius * round(sin(angle + 2*i*pi / n), 10)
v_x = c_x + radius * round(cos(theta), 10)
v_y = c_y + radius * round(sin(theta), 10)
pos[v] = (v_x, v_y)

if return_dict:
Expand Down Expand Up @@ -22857,14 +22858,14 @@ def plot3d(self, bgcolor=(1, 1, 1),
R = rainbow(l)
vertex_colors = {R[i]: partition[i] for i in range(l)}
else:
vertex_colors = {(1, 0, 0) : list(self)}
vertex_colors = {(1, 0, 0): list(self)}

if color_by_label:
if edge_colors is None:
# do the coloring
edge_colors = self._color_by_label(format=color_by_label)
elif edge_colors is None:
edge_colors = {(0, 0, 0) : self.edges(sort=False)}
edge_colors = {(0, 0, 0): self.edges(sort=False)}

# by default turn off the frame
if 'frame' not in kwds:
Expand Down Expand Up @@ -22907,7 +22908,7 @@ def plot3d(self, bgcolor=(1, 1, 1),
edge_colors = self._color_by_label(format=color_by_label)

if edge_colors is None:
edge_colors = {(0, 0, 0) : self.edges(sort=False)}
edge_colors = {(0, 0, 0): self.edges(sort=False)}

i = 0

Expand All @@ -22916,7 +22917,7 @@ def plot3d(self, bgcolor=(1, 1, 1),
TT.texture('edge_color_%d' % i, ambient=0.1, diffuse=0.9,
specular=0.03, opacity=1.0, color=color)
if self._directed:
for u,v,l in edge_colors[color]:
for u, v, l in edge_colors[color]:
TT.fcylinder((pos3d[u][0], pos3d[u][1], pos3d[u][2]),
(pos3d[v][0], pos3d[v][1], pos3d[v][2]),
edge_size, 'edge_color_%d' % i)
Expand Down Expand Up @@ -23606,7 +23607,7 @@ def graphviz_string(self, **options):
color_by_edge = {}
for color in options['edge_colors'].keys():
for edge in options['edge_colors'][color]:
assert isinstance(edge, (list, tuple)) and len(edge) >= 2 and len(edge) <= 3,\
assert isinstance(edge, (list, tuple)) and len(edge) >= 2 and len(edge) <= 3, \
"%s is not a valid format for edge" % (edge)
u = edge[0]
v = edge[1]
Expand Down Expand Up @@ -23668,10 +23669,10 @@ def graphviz_string(self, **options):
'backward': False,
'dot': None,
'edge_string': default_edge_string,
'color' : default_color,
'label' : label,
'color': default_color,
'label': label,
'label_style': options['labels'] if options['edge_labels'] else None
}
}
for f in edge_option_functions:
edge_options.update(f((u, v, label)))

Expand Down Expand Up @@ -25047,8 +25048,10 @@ def is_vertex_transitive(self, partition=None, verbosity=0,
return False

new_partition = self.automorphism_group(partition,
verbosity=verbosity, edge_labels=edge_labels,
order=False, return_group=False, orbits=True)
verbosity=verbosity,
edge_labels=edge_labels,
order=False,
return_group=False, orbits=True)

return (len(partition) == len(new_partition))

Expand Down Expand Up @@ -25904,7 +25907,7 @@ def is_cayley(self, return_group=False, mapping=False,
else:
c = C[0].is_cayley(return_group=False)
elif (not self.allows_loops() and not self.allows_multiple_edges() and
self.density() > Rational(1)/Rational(2)):
self.density() > Rational(1) / Rational(2)):
if certificate:
c, G = self.complement().is_cayley(return_group=True,
allow_disconnected=True)
Expand Down Expand Up @@ -26201,7 +26204,7 @@ def katz_matrix(self, alpha, nonedgesonly=False, vertices=None):

if spectral_radius == 0:
raise ValueError('the spectral radius of the graph must not be zero')
if alpha >= 1/spectral_radius:
if alpha >= 1 / spectral_radius:
raise ValueError('the parameter alpha must be less than the reciprocal of the spectral radius of the graph')

In = matrix.identity(n)
Expand Down
Loading