diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index c3039f68968..efddb03b1cc 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -15746,6 +15746,95 @@ def distance_all_pairs(self, by_weight=False, algorithm=None, weight_function=weight_function, check_weight=check_weight)[0] + def power(self, k): + r""" + Return the `k`-th power graph of ``self``. + + In the `k`-th power graph of a graph `G`, there is an edge between + any pair of vertices at distance at most `k` in `G`, where the + distance is considered in the unweighted graph. In a directed graph, + there is an arc from a vertex `u` to a vertex `v` if there is a path + of length at most `k` in `G` from `u` to `v`. + + INPUT: + + - ``k`` -- integer; the maximum path length for considering edges in + the power graph. + + OUTPUT: + + - The kth power graph based on shortest distances between nodes. + + EXAMPLES: + + Testing on undirected graphs:: + + sage: G = Graph([(0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) + sage: PG = G.power(2) + sage: PG.edges(sort=True, labels=False) + [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (2, 5), (3, 4), (4, 5)] + + Testing on directed graphs:: + + sage: G = DiGraph([(0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) + sage: PG = G.power(3) + sage: PG.edges(sort=True, labels=False) + [(0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 2), (1, 3), (1, 4), (1, 5), (2, 0), (2, 1), (2, 3), (2, 4), (2, 5), (3, 0), (3, 1), (3, 2), (4, 5)] + + TESTS: + + Testing when k < 0:: + + sage: G = Graph([(0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) + sage: PG = G.power(-2) + Traceback (most recent call last): + ... + ValueError: distance must be a non-negative integer, not -2 + + Testing when k = 0:: + + sage: G = Graph([(0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) + sage: PG = G.power(0) + sage: PG.edges(sort=True, labels=False) + [] + + Testing when k = 1:: + + sage: G = Graph([(0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) + sage: PG = G.power(1) + sage: PG.edges(sort=True, labels=False) + [(0, 1), (0, 3), (1, 2), (2, 3), (2, 4), (4, 5)] + + Testing when k = Infinity:: + + sage: G = Graph([(0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) + sage: PG = G.power(Infinity) + Traceback (most recent call last): + ... + ValueError: distance must be a non-negative integer, not +Infinity + + Testing on graph with multiple edges:: + + sage: G = DiGraph([(0, 1), (0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)], multiedges=True) + sage: PG = G.power(3) + sage: PG.edges(sort=True, labels=False) + [(0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 2), (1, 3), (1, 4), (1, 5), (2, 0), (2, 1), (2, 3), (2, 4), (2, 5), (3, 0), (3, 1), (3, 2), (4, 5)] + """ + from sage.graphs.digraph import DiGraph + from sage.graphs.graph import Graph + + power_of_graph = DiGraph() if self.is_directed() else Graph() + + for u in self: + for v in self.breadth_first_search(u, distance=k): + if u != v: + power_of_graph.add_edge(u, v) + + if self.name(): + power_of_graph.name("power({})".format(self.name())) + + return power_of_graph + def girth(self, certificate=False): """ Return the girth of the graph.