Python scipy.sparse.csgraph.shortest_path() Examples

The following are 10 code examples of scipy.sparse.csgraph.shortest_path(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module scipy.sparse.csgraph , or try the search function .
Example #1
Source File: plot_barycenter_fgw.py    From POT with MIT License 7 votes vote down vote up
def find_thresh(C, inf=0.5, sup=3, step=10):
    """ Trick to find the adequate thresholds from where value of the C matrix are considered close enough to say that nodes are connected
        Tthe threshold is found by a linesearch between values "inf" and "sup" with "step" thresholds tested.
        The optimal threshold is the one which minimizes the reconstruction error between the shortest_path matrix coming from the thresholded adjency matrix
        and the original matrix.
    Parameters
    ----------
    C : ndarray, shape (n_nodes,n_nodes)
            The structure matrix to threshold
    inf : float
          The beginning of the linesearch
    sup : float
          The end of the linesearch
    step : integer
            Number of thresholds tested
    """
    dist = []
    search = np.linspace(inf, sup, step)
    for thresh in search:
        Cprime = sp_to_adjency(C, 0, thresh)
        SC = shortest_path(Cprime, method='D')
        SC[SC == float('inf')] = 100
        dist.append(np.linalg.norm(SC - C))
    return search[np.argmin(dist)], dist 
Example #2
Source File: mazes.py    From hpg with MIT License 6 votes vote down vote up
def compute_distance_matrix(self):
        shape = self.layout.shape
        moves = [(-1, 0), (1, 0), (0, -1), (0, 1)]

        adj_matrix = np.zeros((self.layout.size, self.layout.size))

        for (r, c) in self.valid_positions:
            index = np.ravel_multi_index((r, c), shape)

            for move in moves:
                nr, nc = r + move[0], c + move[1]

                if (nr, nc) in self.valid_positions:
                    nindex = np.ravel_multi_index((nr, nc), shape)
                    adj_matrix[index, nindex] = 1

        self.dist_matrix = shortest_path(adj_matrix) 
Example #3
Source File: seal_link_pred.py    From pytorch_geometric with MIT License 5 votes vote down vote up
def drnl_node_labeling(self, edge_index, src, dst, num_nodes=None):
        # Double-radius node labeling (DRNL).
        src, dst = (dst, src) if src > dst else (src, dst)
        adj = to_scipy_sparse_matrix(edge_index, num_nodes=num_nodes).tocsr()

        idx = list(range(src)) + list(range(src + 1, adj.shape[0]))
        adj_wo_src = adj[idx, :][:, idx]

        idx = list(range(dst)) + list(range(dst + 1, adj.shape[0]))
        adj_wo_dst = adj[idx, :][:, idx]

        dist2src = shortest_path(adj_wo_dst, directed=False, unweighted=True)
        dist2src = dist2src[:, src]
        dist2src = np.insert(dist2src, dst, 0, axis=0)
        dist2src = torch.from_numpy(dist2src)

        dist2dst = shortest_path(adj_wo_src, directed=False, unweighted=True)
        dist2dst = dist2dst[:, dst - 1]
        dist2dst = np.insert(dist2dst, src, 0, axis=0)
        dist2dst = torch.from_numpy(dist2dst)

        dist = dist2src + dist2dst
        dist_over_2, dist_mod_2 = dist // 2, dist % 2

        z = 1 + torch.min(dist2src, dist2dst)
        z += dist_over_2 * (dist_over_2 + dist_mod_2 - 1)
        z[src] = 1.
        z[dst] = 1.
        z[torch.isnan(z)] = 0.

        self.__max_z__ = max(int(z.max()), self.__max_z__)

        return z.to(torch.long) 
Example #4
Source File: router.py    From c3nav-32c3 with Apache License 2.0 5 votes vote down vote up
def create_routing_table(self):
        self.excluded_nodes, g_dense = Router.create_dense_matrix(self.graph, tuple(self.settings.items()))
        self.shortest_paths, self.predecessors = Router.shortest_path(g_dense.tostring(), g_dense.shape) 
Example #5
Source File: router.py    From c3nav-32c3 with Apache License 2.0 5 votes vote down vote up
def shortest_path(cls, data, shape):
        # let scipy do it's magic and calculate all shortest paths in the remaining graph
        g_sparse = csr_matrix(np.ma.masked_values(np.fromstring(data).reshape(shape), 0))
        return shortest_path(g_sparse, return_predecessors=True) 
Example #6
Source File: gromov_hausdorff.py    From persim with MIT License 5 votes vote down vote up
def make_distance_matrix_from_adjacency_matrix(AG):
    """
    Represent simple unweighted graph as compact metric space (with
    integer distances) based on its shortest path lengths.

    Parameters
    -----------
    AG: np.array (|V(G)|×|V(G)|)
        (Sparse) adjacency matrix of simple unweighted graph G.

    Returns
    --------
    DG: np.array (|V(G)|×|V(G)|)
        (Dense) distance matrix of the compact metric space
        representation of G based on its shortest path lengths.
    """
    # Convert adjacency matrix to SciPy format if needed.
    if not sps.issparse(AG) and not isinstance(AG, np.ndarray):
        AG = np.asarray(AG)

    # Compile distance matrix of the graph based on its shortest path
    # lengths.
    DG = shortest_path(AG, directed=False, unweighted=True)
    # Ensure compactness of metric space, represented by distance
    # matrix.
    if np.any(np.isinf(DG)):
        warnings.warn("disconnected graph is approximated by its largest connected component")
        # Extract largest connected component of the graph.
        _, components_by_vertex = connected_components(AG, directed=False)
        components, component_sizes = np.unique(components_by_vertex, return_counts=True)
        largest_component = components[np.argmax(component_sizes)]
        DG = DG[components_by_vertex == largest_component]

    # Cast distance matrix to optimal integer type.
    DG = cast_distance_matrix_to_optimal_int_type(DG)

    return DG 
Example #7
Source File: grid.py    From pysheds with GNU General Public License v3.0 4 votes vote down vote up
def _d8_flow_distance(self, x, y, fdir, weights=None, dirmap=None, nodata_in=None,
                          nodata_out=0, out_name='dist', method='shortest', inplace=True,
                          xytype='index', apply_mask=True, ignore_metadata=False, properties={},
                          metadata={}, snap='corner', **kwargs):
        # Construct flat index onto flow direction array
        domain = np.arange(fdir.size)
        fdir_orig_type = fdir.dtype
        if nodata_in is None:
            nodata_cells = np.zeros_like(fdir).astype(bool)
        else:
            if np.isnan(nodata_in):
                nodata_cells = (np.isnan(fdir))
            else:
                nodata_cells = (fdir == nodata_in)
        try:
            mintype = np.min_scalar_type(fdir.size)
            fdir = fdir.astype(mintype)
            domain = domain.astype(mintype)
            startnodes, endnodes = self._construct_matching(fdir, domain,
                                                            dirmap=dirmap)
            if xytype == 'label':
                x, y = self.nearest_cell(x, y, fdir.affine, snap)
            # TODO: Currently the size of weights is hard to understand
            if weights is not None:
                weights = weights.ravel()
                assert(weights.size == startnodes.size)
                assert(weights.size == endnodes.size)
            else:
                assert(startnodes.size == endnodes.size)
                weights = (~nodata_cells).ravel().astype(int)
            C = scipy.sparse.lil_matrix((fdir.size, fdir.size))
            for i,j,w in zip(startnodes, endnodes, weights):
                C[i,j] = w
            C = C.tocsr()
            xyindex = np.ravel_multi_index((y, x), fdir.shape)
            dist = csgraph.shortest_path(C, indices=[xyindex], directed=False)
            dist[~np.isfinite(dist)] = nodata_out
            dist = dist.ravel()
            dist = dist.reshape(fdir.shape)
        except:
            raise
        finally:
            self._unflatten_fdir(fdir, domain, dirmap)
            fdir = fdir.astype(fdir_orig_type)
        # Prepare output
        return self._output_handler(data=dist, out_name=out_name, properties=properties,
                                    inplace=inplace, metadata=metadata) 
Example #8
Source File: segmentation.py    From kraken with Apache License 2.0 4 votes vote down vote up
def _interpolate_lines(clusters, elongation_offset, extent, st_map, end_map):
    """
    Interpolates the baseline clusters and sets the correct line direction.
    """
    logger.debug('Reticulating splines')
    lines = []
    extent = geom.Polygon([(0, 0), (extent[1]-1, 0), (extent[1]-1, extent[0]-1), (0, extent[0]-1), (0, 0)])
    f_st_map = maximum_filter(st_map, size=20)
    f_end_map = maximum_filter(end_map, size=20)
    for cluster in clusters[1:]:
        # find start-end point
        points = [point for edge in cluster for point in edge]
        dists = squareform(pdist(points))
        i, j = np.unravel_index(dists.argmax(), dists.shape)
        # build adjacency matrix for shortest path algo
        adj_mat = np.full_like(dists, np.inf)
        for l, r in cluster:
            idx_l = points.index(l)
            idx_r = points.index(r)
            adj_mat[idx_l, idx_r] = dists[idx_l, idx_r]
        # shortest path
        _, pr = shortest_path(adj_mat, directed=False, return_predecessors=True, indices=i)
        k = j
        line = [points[j]]
        while pr[k] != -9999:
            k = pr[k]
            line.append(points[k])
        # smooth line
        line = np.array(line[::-1])
        line = approximate_polygon(line[:,[1,0]], 1)
        lr_dir = line[0] - line[1]
        lr_dir = (lr_dir.T  / np.sqrt(np.sum(lr_dir**2,axis=-1))) * elongation_offset/2
        line[0] = line[0] + lr_dir
        rr_dir = line[-1] - line[-2]
        rr_dir = (rr_dir.T  / np.sqrt(np.sum(rr_dir**2,axis=-1))) * elongation_offset/2
        line[-1] = line[-1] + rr_dir
        ins = geom.LineString(line).intersection(extent)
        if ins.type == 'MultiLineString':
            ins = linemerge(ins)
            # skip lines that don't merge cleanly
            if ins.type != 'LineString':
                continue
        line = np.array(ins, dtype='uint')
        l_end = tuple(line[0])[::-1]
        r_end = tuple(line[-1])[::-1]
        if f_st_map[l_end] - f_end_map[l_end] > 0.2 and f_st_map[r_end] - f_end_map[r_end] < -0.2:
            pass
        elif f_st_map[l_end] - f_end_map[l_end] < -0.2 and f_st_map[r_end] - f_end_map[r_end] > 0.2:
            line = line[::-1]
        else:
            logger.debug('Insufficient marker confidences in output. Defaulting to upright line.')
            if line[0][0] > line[-1][0]:
                line = line[::-1]
        lines.append(line.tolist())
    return lines 
Example #9
Source File: isomap.py    From megaman with BSD 2-Clause "Simplified" License 4 votes vote down vote up
def fit(self, X, y=None, input_type='data'):
        """Fit the model from data in X.

        Parameters
        ----------
        input_type : string, one of: 'data', 'distance'.
            The values of input data X. (default = 'data')

        X : array-like, shape (n_samples, n_features)
            Training vector, where n_samples in the number of samples
            and n_features is the number of features.

        If self.input_type is 'distance':

        X : array-like, shape (n_samples, n_samples),
            Interpret X as precomputed distance or adjacency graph
            computed from samples.

        eigen_solver : {None, 'arpack', 'lobpcg', or 'amg'}
            The eigenvalue decomposition strategy to use. AMG requires pyamg
            to be installed. It can be faster on very large, sparse problems,
            but may also lead to instabilities.

        Returns
        -------
        self : object
            Returns the instance itself.
        """

        X = self._validate_input(X, input_type)
        self.fit_geometry(X, input_type)

        if not hasattr(self, 'distance_matrix'):
            self.distance_matrix = None
        if not hasattr(self, 'graph_distance_matrix'):
            self.graph_distance_matrix = None
        if not hasattr(self, 'centered_matrix'):
            self.centered_matrix = None

        # don't re-compute these if it's already been done.
        # This might be the case if an eigendecompostion fails and a different sovler is selected
        if (self.distance_matrix is None and self.geom_.adjacency_matrix is None):
            self.distance_matrix = self.geom_.compute_adjacency_matrix()
        elif self.distance_matrix is None:
            self.distance_matrix = self.geom_.adjacency_matrix
        if self.graph_distance_matrix is None:
            self.graph_distance_matrix = graph_shortest_path(self.distance_matrix,
                                                             method = self.path_method,
                                                             directed = False)
        if self.centered_matrix is None:
            self.centered_matrix = center_matrix(self.graph_distance_matrix)

        self.embedding_ = isomap(self.geom_, n_components=self.n_components,
                                 eigen_solver=self.eigen_solver,
                                 random_state=self.random_state,
                                 path_method = self.path_method,
                                 distance_matrix = self.distance_matrix,
                                 graph_distance_matrix = self.graph_distance_matrix,
                                 centered_matrix = self.centered_matrix,
                                 solver_kwds = self.solver_kwds)
        return self 
Example #10
Source File: transform_manager.py    From pytransform3d with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
def add_transform(self, from_frame, to_frame, A2B):
        """Register a transform.

        Parameters
        ----------
        from_frame : str
            Name of the frame for which the transform is added in the to_frame
            coordinate system

        to_frame : str
            Name of the frame in which the transform is defined

        A2B : array-like, shape (4, 4)
            Homogeneous matrix that represents the transform from 'from_frame'
            to 'to_frame'

        Returns
        -------
        self : TransformManager
            This object for chaining
        """
        A2B = check_transform(A2B, strict_check=self.strict_check)
        if from_frame not in self.nodes:
            self.nodes.append(from_frame)
        if to_frame not in self.nodes:
            self.nodes.append(to_frame)

        if (from_frame, to_frame) not in self.transforms:
            self.i.append(self.nodes.index(from_frame))
            self.j.append(self.nodes.index(to_frame))

        self.transforms[(from_frame, to_frame)] = A2B

        n_nodes = len(self.nodes)
        self.connections = sp.csr_matrix(
            (np.zeros(len(self.i)), (self.i, self.j)),
            shape=(n_nodes, n_nodes))
        self.dist, self.predecessors = csgraph.shortest_path(
            self.connections, unweighted=True, directed=False, method="D",
            return_predecessors=True)

        return self