def minimum_spanning_tree(self, distance, write=False, write_edge_label=None, start_node=None): """Compute the minimum spanning tree. Parameters ---------- distance : str Distance to minimize when computing the minimum spanning tree (MST) write : bool, optional Flag indicating whether the MST should be returned as a new graph object or saved within a Boolean edge property being True whenever a given edge belongs to the MST. write_edge_label : str, optional Edge label for creating edges beloning to the MST. Returns ------- tree : graph object The minimum spanning tree graph object (backend-dependent) """ if write is False: raise PathFinder.PathSearchException( "Minimum spanning tree computation with " "the parameter `write=False` is currently is not " "supported for Neo4j graphs") else: if write_edge_label is None: raise PathFinder.PathSearchException( "The minimum spanning tree computation " "has the `write` option set to `True`, " "the write property name must be specified") if start_node is not None: head = "MATCH (n:{} {{id: '{}'}})\n".format( self.node_label, start_node) else: head = ("MATCH (n:{})\n".format(self.node_label) + "WITH n, rand() as r ORDER BY r LIMIT 1\n") graph = self._get_identity_view() query = (head + "CALL gds.alpha.spanningTree.minimum.write({\n" + graph.get_projection_query(distance) + "," " startNodeId: id(n),\n" " relationshipWeightProperty: '{}',\n".format(distance) + " writeProperty: '{}',\n".format(write_edge_label) + " weightWriteProperty: 'writeCost'\n" "})\n" "YIELD createMillis, computeMillis, writeMillis\n" "RETURN createMillis, computeMillis, writeMillis") self.execute(query)
def _compute_all_shortest_paths(graph, s, t, exclude_edge=False): try: all_paths = [tuple(p) for p in nx.all_shortest_paths(graph, s, t)] except nx.exception.NetworkXNoPath: raise PathFinder.NoPathException( "Path from '{}' to '{}' does not exist".format(s, t)) return all_paths
def minimum_spanning_tree(self, distance, write=False, write_property=None): """Compute the minimum spanning tree. Parameters ---------- distance : str Distance to minimize when computing the minimum spanning tree (MST) write : bool, optional Flag indicating whether the MST should be returned as a new graph object or saved within a Boolean edge property being True whenever a given edge belongs to the MST. write_property : str, optional Edge property name for marking edges beloning to the MST. Returns ------- tree : nx.Graph The minimum spanning tree graph object """ tree = nx.minimum_spanning_tree(self.graph, weight=distance) if write: if write_property is None: raise PathFinder.PathSearchException( "The minimum spanning tree finder has the write option set " "to True, the write property name must be specified") mst_property = {} for e in self.graph.edges(): mst_property[e] = e in tree.edges() nx.set_edge_attributes(self.graph, mst_property, write_property) else: return tree
def n_shortest_paths(self, source, target, n, distance=None, strategy="naive", exclude_edge=False): """Compute n shortest paths from the source to the target. Two search strategies are available: 'naive' and 'yen'. The naive strategy first finds the set of all shortest paths from the source to the target node, it then ranks them by the cumulative distance score and returns n best paths. The second strategy uses Yen's algorithm [1] for finding n shortest paths. The first naive strategy performs better for highly dense graphs (where every node is connected to almost every other node). Note that if there are less than n unweighted shortest paths in the graph, the naive strategy may return less than n paths. 1. Yen, Jin Y. "Finding the k shortest loopless paths in a network". Management Science 17.11 (1971): 712-716. Parameters ---------- source : str Source node ID target : str Target node ID n : int Number of top paths to include in the result distance : str, optional The name of the attribute to use as the edge distance path_condition : func, optional Edge filtering function returning Boolean flag strategy : str, optional Path finding strategy: `naive` or `yen`. By default, `naive`. exclude_edge : bool, optional Flag indicating whether the direct edge from the source to the target should be excluded from the result (if exists). Returns ------- paths : list List containing top n best paths according to the distance score """ if strategy == "yen": raise PathFinder.NotImplementedError( "Yen's algorithm for finding n shortest paths " "is currently not implemented") else: return super().n_shortest_paths(source, target, n, distance=distance, strategy="naive", exclude_edge=exclude_edge)
def _compute_yen_shortest_paths(graph, source, target, n, distance, exclude_edge=False): """Compute n shortest paths using the Yen's algo.""" raise PathFinder.NotImplementedError( "Yen's algorithm for finding n shortest paths " "is currently not implemented for graph-tool backend")
def _compute_yen_shortest_paths(graph, source, target, n=None, distance=None, exclude_edge=False): if n is None: raise PathFinder.PathSearchException( "Number of paths must be specified when calling" "`NXPathFinder.compute_yen_shortest_paths`") generator = nx.shortest_simple_paths(graph, source, target, weight=distance) i = 0 paths = [] for path in generator: paths.append(tuple(path)) i += 1 if i == n: break return paths
def minimum_spanning_tree(self, distance, write=False, write_property=None): """Compute the minimum spanning tree. Parameters ---------- distance : str Distance to minimize when computing the minimum spanning tree (MST) write : bool, optional Flag indicating whether the MST should be returned as a new graph object or saved within a Boolean edge property being True whenever a given edge belongs to the MST. write_property : str, optional Edge property name for marking edges beloning to the MST. Returns ------- tree : nx.Graph The minimum spanning tree graph object """ mst_property = min_spanning_tree(self.graph, weights=self.graph.ep[distance]) if write: if write_property is None: raise PathFinder.PathSearchException( "The minimum spanning tree finder has the write option set " "to True, the write property name must be specified") self.graph.ep[write_property] = mst_property else: tree = GraphView(self.graph, efilt=mst_property) return tree