def test_minimum_spanning_tree(): np.random.seed(1234) for N in (5, 10, 15, 20): # Create a graph as above where every edge is >= 3 except at # most N that are 2. graph = 3 + np.random.random((N, N)) ind = np.random.randint(N, size=(2, N * N / 2)) graph[ind[0], ind[1]] = 2 csgraph = csr_matrix(graph) # We thus expect at most N+1 in the spanning tree. mintree = minimum_spanning_tree(csgraph) assert_(mintree.nnz < N) # Now set the sub diagonal to 1, to create a known spanning tree. idx = np.arange(N-1) graph[idx,idx+1] = 1 csgraph = csr_matrix(graph) mintree = minimum_spanning_tree(csgraph) # We expect to see this pattern in the spanning tree and otherwise # have this zero. expected = np.zeros((N,N)) expected[idx,idx+1] = 1 npt.assert_array_equal(mintree.todense(), expected, 'Incorrect spanning tree found.')
def test_minimum_spanning_tree(): # Create a graph with two connected components. graph = [[0,1,0,0,0], [1,0,0,0,0], [0,0,0,8,5], [0,0,8,0,1], [0,0,5,1,0]] graph = np.asarray(graph) # Create the expected spanning tree. expected = [[0,1,0,0,0], [0,0,0,0,0], [0,0,0,0,5], [0,0,0,0,1], [0,0,0,0,0]] expected = np.asarray(expected) # Ensure minimum spanning tree code gives this expected output. csgraph = csr_matrix(graph) mintree = minimum_spanning_tree(csgraph) npt.assert_array_equal(mintree.todense(), expected, 'Incorrect spanning tree found.') # Ensure that the original graph was not modified. npt.assert_array_equal(csgraph.todense(), graph, 'Original graph was modified.') # Now let the algorithm modify the csgraph in place. mintree = minimum_spanning_tree(csgraph, overwrite=True) npt.assert_array_equal(mintree.todense(), expected, 'Graph was not properly modified to contain MST.') np.random.seed(1234) for N in (5, 10, 15, 20): # Create a random graph. graph = 3 + np.random.random((N, N)) csgraph = csr_matrix(graph) # The spanning tree has at most N - 1 edges. mintree = minimum_spanning_tree(csgraph) assert_(mintree.nnz < N) # Set the sub diagonal to 1 to create a known spanning tree. idx = np.arange(N-1) graph[idx,idx+1] = 1 csgraph = csr_matrix(graph) mintree = minimum_spanning_tree(csgraph) # We expect to see this pattern in the spanning tree and otherwise # have this zero. expected = np.zeros((N, N)) expected[idx, idx+1] = 1 npt.assert_array_equal(mintree.todense(), expected, 'Incorrect spanning tree found.')
def getSimMSTs(self, inverse=True, plotGraph=True, root="UNK"): rootId1 = self.emb1.d[root] rootId2 = self.emb2.d[root] if inverse == True: d = -1 else: d = 1 g1 = minimum_spanning_tree(csr_matrix(d*self.s1)) g2 = minimum_spanning_tree(csr_matrix(d*self.s2)) a1 = g1.toarray() a2 = g2.toarray() if plotGraph==True: t1 = Graph() t2 = Graph() t3 = Graph() t1.add_vertices(self.emb1.vocab_size) t2.add_vertices(self.emb2.vocab_size) t3.add_vertices(self.emb1.vocab_size) t1.vs["color"] = "white" t2.vs["color"] = "white" t3.vs["color"] = "white" t1.vs["label"] = [w for w,i in sorted(self.emb1.d.items(), key=itemgetter(1))] t2.vs["label"] = [w for w,i in sorted(self.emb2.d.items(), key=itemgetter(1))] t3.vs["label"] = t1.vs["label"] for i in xrange(a1.shape[0]): for j in xrange(a1.shape[1]): if a1[i,j] != 0: t1.add_edge(i,j, weight=a1[i,j], color="blue") t3.add_edge(i,j, weight=a1[i,j], color="blue") for i in xrange(a2.shape[0]): for j in xrange(a2.shape[1]): if a2[i,j] != 0: t2.add_edge(i,j, weight=a2[i,j], color="red") if t3.are_connected(i,j): #edge in both MSTs t3.es[i,j]["color"] = "black" else: t3.add_edge(i,j, weight=a1[i,j], color="red") layout1 = t1.layout_reingold_tilford(mode="in", root=rootId1) layout2 = t2.layout_reingold_tilford(mode="in", root=rootId2) layout3 = t3.layout_reingold_tilford(mode="in", root=rootId1) graphs = [Graph.GRG(10, 0.4) for _ in xrange(5)] figure = Plot(bbox=(0,0,2000,1000)) figure.add(t1, layout=layout1, margin=100, bbox=(0,0,1000,1000)) figure.add(t2, layout=layout2, margin=100, bbox=(1000,0,2000,1000)) plotname1 = "plots/"+NAME+".mst_trees.png" figure.save(plotname1) plotname3 = "plots/"+NAME+".merged_mst.png" plot(t3, plotname3 , layout=layout3, bbox=(1000,1000), margin=100) print("\tSaved MST plots in '%s', '%s'" % (plotname1, plotname3)) return t1,t2,t3
def disjoint_mst(X, num_spanning_trees=3, metric='euclidean'): '''Builds a graph as the union of several spanning trees, each time removing any edges present in previously-built trees. Reference: http://ecovision.mit.edu/~sloop/shao.pdf, page 9.''' D = _pdist(X, metric) mst = minimum_spanning_tree(D) W = mst.copy() for i in range(1, num_spanning_trees): ii,jj = mst.nonzero() D[ii,jj] = np.inf D[jj,ii] = np.inf mst = minimum_spanning_tree(D) W = W + mst # MSTs are all one-sided, so we symmetrize here return Graph.from_adj_matrix(W + W.T)
def find_mst_bridge(self): if not hasattr(self, 'distMat'): self.get_all_bridge() # MST bridges with breadth_first_order distMatMst = csg.minimum_spanning_tree(self.distMat) succs, preds = csg.breadth_first_order(distMatMst, i_start=self.labelRef-1, directed=False) # save to self.bridges self.bridges = [] for i in range(1, succs.size): n0 = preds[succs[i]] + 1 n1 = succs[i] + 1 # read conn nn = sorted([str(n0), str(n1)]) conn = self.connDict['{}{}'.format(nn[0], nn[1])] y0, x0 = conn[str(n0)] y1, x1 = conn[str(n1)] # save bdg bridge = dict() bridge['x0'] = x0 bridge['y0'] = y0 bridge['x1'] = x1 bridge['y1'] = y1 bridge['label0'] = n0 bridge['label1'] = n1 self.bridges.append(bridge) self.num_bridge = len(self.bridges) return
def minimum_spanning_subtree(self): '''Returns the (undirected) minimum spanning tree subgraph.''' dist = self.matrix(dense=True, copy=True) dist[dist==0] = np.inf np.fill_diagonal(dist, 0) mst = ssc.minimum_spanning_tree(dist) return self.__class__.from_adj_matrix(mst + mst.T)
def examinalyze(smat): mst = minimum_spanning_tree(smat) connections = np.where(mst.toarray()) lines = [(coords[ii], coords[jj]) for ii,jj in zip(*connections)] plotlines = [((a.ra.deg, b.ra.deg), (a.dec.deg, b.dec.deg)) for a,b in lines] xx,yy = np.array(list(zip(*plotlines))) lines2 = [(coords[ll], coords[rr]) for ll,rr in edges] plotlines2 = [((a.ra.deg, b.ra.deg), (a.dec.deg, b.dec.deg)) for a,b in lines2] xx2,yy2 = np.array(list(zip(*plotlines2))) import pylab as pl pl.clf() pl.plot(coords.ra.deg, coords.dec.deg, '*') pl.plot(xx.T, yy.T, color='b', alpha=0.5, linewidth=2) pl.plot(xx2.T, yy2.T, color='r', alpha=0.5, linewidth=2) inds = np.where(np.tril(smat, -1)) mps = smat[inds].mean() mbl = mst[mst.nonzero()].mean() print("Mean branch length: {0} arcsec {1}".format(mbl*3600, (mbl*u.deg*distance).to(u.pc, u.dimensionless_angles()))) print("Mean point separation: {0} arcsec {1}".format(mps*3600, (mbl*u.deg*distance).to(u.pc, u.dimensionless_angles()))) print("Q parameter: {0}".format(mbl/mps))
def join_clusters(self): # Generate an empty, N x N sparse graph node_count = len(self.clusters) dense = np.zeros((node_count, node_count), dtype=float) expand = {} cluster_pairs = itertools.combinations(self.clusters, 2) for cluster_pair in cluster_pairs: weights, segs = self.compute_edge_weights(*cluster_pair) c1_index = self.clusters.index(cluster_pair[0]) c2_index = self.clusters.index(cluster_pair[1]) dense[c1_index, c2_index] = weights[0] dense[c2_index, c1_index] = weights[1] expand[(c1_index, c2_index)] = segs[1] expand[(c2_index, c1_index)] = segs[0] sparse = sp.csgraph_from_dense(dense) mst = sp.minimum_spanning_tree(sparse) edges = mst.nonzero() edges = zip(edges[0], edges[1]) for edge in edges: cluster = self.clusters[edge[0]] cluster.add(expand[edge]) cluster.intersections.append(self.clusters[edge[1]])
def test_is_forest(): # generate chain chain = np.c_[np.arange(1, 10), np.arange(9)] assert_true(is_forest(chain, len(chain) + 1)) assert_true(is_forest(chain)) # generate circle circle = np.vstack([chain, [9, 0]]) assert_false(is_forest(circle)) assert_false(is_forest(circle, len(chain) + 1)) # union of two disjoint chains two_chains = np.vstack([chain, chain + 10]) assert_true(is_forest(two_chains, 20)) # union of chain and circle disco_graph = np.vstack([chain, circle + 10]) assert_false(is_forest(disco_graph)) # generate random fully connected graph graph = np.random.uniform(size=(10, 10)) edges = np.c_[graph.nonzero()] assert_false(is_forest(edges)) try: from scipy.sparse.csgraph import minimum_spanning_tree tree = minimum_spanning_tree(sparse.csr_matrix(graph)) tree_edges = np.c_[tree.nonzero()] assert_true(is_forest(tree_edges, 10)) assert_true(is_forest(tree_edges)) except ImportError: pass
def learnStructure(dataP, dataS, Pp, Ps, TAN= True): tempMatrix = [[0 for i in range(len(dataP))] for j in range(len(dataP))] for i in range(len(dataP)): for j in range(i+1, len(dataP)): temp = 0.0 if np.corrcoef(dataP[i], dataP[j])[0][1] != 1.0: temp += Pp * math.log(1-((np.corrcoef(dataP[i], dataP[j])[0][1])**2)) if np.corrcoef(dataS[i], dataS[j])[0][1] != 1.0: temp += Ps * math.log(1-((np.corrcoef(dataS[i], dataS[j])[0][1])**2)) temp *= (0.5) tempMatrix[i][j] = temp #tempMatrix[j][i] = temp MaxG = nx.DiGraph() if TAN: G = nx.from_scipy_sparse_matrix(minimum_spanning_tree(csr_matrix(tempMatrix))) adjList = G.adj i = 0 notReturnable = {} MaxG = getDirectedTree(adjList, notReturnable, MaxG, i) else: G = nx.Graph(np.asmatrix(tempMatrix)) adjList = sorted([(u,v,d['weight']) for (u,v,d) in G.edges(data=True)], key=lambda x:x[2]) i = 2 MaxG = getDirectedGraph(adjList, MaxG, i) return MaxG
def _generateFeedback(self, **kwargs): distances = utils.pairwise(self.representatives, self.distance, self.symmetric_distance) mst = csgraph.minimum_spanning_tree(distances) distances = csgraph.shortest_path(mst,method="D", directed=False) super(MinimumSpanningTreeFeedback, self). generateFeedback(distances, **kwargs)
def split_dist_matrix(dist_matrix, overwrite=False): # Create the minimum spanning tree. # `overwrite=True` will make changes in place, which is more efficient. mst = minimum_spanning_tree(csr_matrix(dist_matrix), overwrite=overwrite) mst = mst.toarray() # Get the index of the maximum value. # `argmax` returns the index of the _flattened_ array; # `unravel_index` converts it back. idx = np.unravel_index(mst.argmax(), mst.shape) # Clear out the maximum value to split the tree. mst[idx] = 0 # Label connected components. num_graphs, labels = connected_components(mst, directed=False) # We should have two trees. assert(num_graphs == 2) # Use indices as node ids and group them according to their graph. results = [[] for i in range(max(labels) + 1)] for idx, label in enumerate(labels): results[label].append(idx) return results
def _randomly_divide_connected_graph(adj, n_regions): """ Divide the provided connected graph into `n_regions` regions. Parameters ---------- adj : :class:`scipy.sparse.csr_matrix` Adjacency matrix. n_regions : int The desired number of clusters. Must be > 0 and <= number of nodes. Returns ------- labels : :class:`numpy.ndarray` Each element (an integer in {0, ..., `n_regions` - 1}) specifies the region an area (defined by the index in the array) belongs to. Examples -------- >>> from scipy.sparse import diags >>> n_nodes = 10 >>> adj_diagonal = [1] * (n_nodes-1) >>> # 10x10 adjacency matrix representing the path 0-1-2-...-9-10 >>> adj = diags([adj_diagonal, adj_diagonal], offsets=[-1, 1]) >>> n_regions_desired = 4 >>> labels = _randomly_divide_connected_graph(adj, n_regions_desired) >>> n_regions_obtained = len(set(labels)) >>> n_regions_desired == n_regions_obtained True """ if not n_regions > 0: msg = "n_regions is {} but must be positive.".format(n_regions) raise ValueError(msg) n_areas = adj.shape[0] if not n_regions <= n_areas: msg = "n_regions is {} but must less than or equal to " + \ "the number of nodes which is {}".format(n_regions, n_areas) raise ValueError(msg) mst = csg.minimum_spanning_tree(adj) for _ in range(n_regions - 1): # try different links to cut and pick the one leading to the most # balanced solution best_link = None max_region_size = float("inf") for __ in range(5): mst_copy = mst.copy() nonzero_i, nonzero_j = mst_copy.nonzero() random_position = random.randrange(len(nonzero_i)) i, j = nonzero_i[random_position], nonzero_j[random_position] mst_copy[i, j] = 0 mst_copy.eliminate_zeros() labels = csg.connected_components(mst_copy, directed=False)[1] max_size = max(np.unique(labels, return_counts=True)[1]) if max_size < max_region_size: best_link = (i, j) max_region_size = max_size mst[best_link[0], best_link[1]] = 0 mst.eliminate_zeros() return csg.connected_components(mst)[1]
def minimal_spanning_tree(self): """ Create a minimal spanning tree using the distance correction method given. You can explore different distance corrections in topslam.pseudo_time.distances. """ if getattr(self, '_mst', None) is None: self._mst = minimum_spanning_tree(self.manifold_corrected_distance_matrix) return self._mst
def compute_mst(self, indexes=None): """ Compute the MST over the segments :return: """ adj_matrix = self._compute_adjacency_matrix(indexes) tree = sp.minimum_spanning_tree(adj_matrix) return tree
def extract_manifold_distances_mst(D): """ Return the distances along a minimal spanning tree for the given distances D (Using dijkstra). It also returns the mst itself. returns [distances along mst, mst] """ # First do the minimal spanning tree distances mst = minimum_spanning_tree(D) return dijkstra(mst, directed=False, return_predecessors=False), mst
def chow_liu_tree(y_): n_labels = y_.shape[1] mi = np.zeros((n_labels, n_labels)) for i in range(n_labels): for j in range(n_labels): mi[i, j] = mutual_info_score(y_[:, i], y_[:, j]) mst = minimum_spanning_tree(csr_matrix(-mi)) edges = np.vstack(mst.nonzero()).T edges.sort(axis=1) return edges
def spanning_tree_length(X): """Compute the length of the euclidean MST of X. Parameters ---------- X: ndarray, shape=[n_samples, n_features] """ if X.shape[0] < 2: return 0 return minimum_spanning_tree(euclidean_distances(X)).sum()
def _Minimum_SPTree_log_probs(self, log_probs, log_c_probs): """ the tree is represented as a sequence of parents""" mst = minimum_spanning_tree(-(self.MI)) dfs_tree = depth_first_order(mst, directed=False, i_start=0) self.df_order = dfs_tree[0] self.tree = self.create_tree(dfs_tree) # computing the factored representation self.log_factors = np.zeros((self.n_features, 2, 2)) self.log_factors = compute_log_factors(self.tree, self.n_features, log_probs, log_c_probs, self.log_factors)
def runNetView(self, tree=True, start=10, stop=40, step=10, algorithm='auto'): print(get_time() + "\t" + "Minimum Spanning Tree = " + str(tree).upper()) print(get_time() + "\t" + "Nearest Neighbour = " + algorithm.upper()) print(get_time() + "\t" + "k = " + str(start) + " - " + str(stop) + ' (by ' + str(step) + ')') print(get_time() + "\t" + "---------------------------------") self.data.netview_runs += 1 matrix = self.data.matrix if tree: mst = csg.minimum_spanning_tree(matrix) mst = mst.toarray() self.data.networks['mst_' + str(self.data.netview_runs)] = mst mst = mst + mst.T else: mst = None pool = mp.Pool() networks = [pool.apply_async(netview, args=(matrix, k, mst, algorithm, tree,), callback=netview_callback) for k in range(start, stop+1, step)] pool.close() pool.join() for item in networks: result = item.get() edges_array = result[1] edges = result[1].tolist() mst_edges = result[4].tolist() self.data.networks['netview_k' + str(result[0]) + '_' + str(self.data.netview_runs)] = result[1:] filename = self.data.prefix + '_netview_k' + str(result[0]) +\ "_" + str(self.data.netview_runs) + '.edges' out = open(filename, "w") out.write('Source\tTarget\tDistance\tMST\n') for i in range(len(edges)): out.write(str(self.data.ids[edges[i][0]]) + "\t" + str(self.data.ids[edges[i][1]]) + "\t" + str(matrix[edges[i][0], edges[i][1]])) if tree: if edges[i] in mst_edges: out.write('\t' + 'red\n') else: out.write('\t' + 'grey\n') else: out.write("\n") if not tree: singletons = np.setdiff1d(np.arange(self.data.n), edges_array.flatten()).tolist() if singletons: for node in singletons: out.write(str(node) + '\n') out.close()
def get_mst(adj_mat): X = csr_matrix(adj_mat) # print adj_mat Tcsr = minimum_spanning_tree(X) mst = Tcsr.toarray().astype(int) weights = [] for row in mst: for value in row[np.nonzero(row)]: weights.append(value) # print weights return mst, weights
def perturbed_mst(X, num_perturbations=20, metric='euclidean', jitter=None): '''Builds a graph as the union of several MSTs on perturbed data. Reference: http://ecovision.mit.edu/~sloop/shao.pdf, page 8 jitter refers to the scale of the gaussian noise added for each perturbation. When jitter is None, it defaults to the 5th percentile interpoint distance. Note that metric cannot be 'precomputed', as multiple MSTs are computed.''' D = pairwise_distances(X, metric=metric) if jitter is None: jitter = np.percentile(D[D>0], 5) W = minimum_spanning_tree(D) W = W + W.T W.data[:] = 1.0 # binarize for i in range(num_perturbations): pX = X + np.random.normal(scale=jitter, size=X.shape) pW = minimum_spanning_tree(pairwise_distances(pX, metric=metric)) pW = pW + pW.T pW.data[:] = 1.0 W = W + pW # final graph is the average over all pertubed MSTs + the original W.data /= (num_perturbations + 1.0) return Graph.from_adj_matrix(W)
def intra_encounter_matching(): import numpy as np from scipy.sparse import coo_matrix, csgraph qreq_, cm_list = testdata_workflow() # qaids = [cm.qaid for cm in cm_list] # top_aids = [cm.get_top_aids(5) for cm in cm_list] aid_pairs = np.array([(cm.qaid, daid) for cm in cm_list for daid in cm.get_top_aids(5)]) top_scores = ut.flatten([cm.get_top_scores(5) for cm in cm_list]) N = aid_pairs.max() + 1 mat = coo_matrix((top_scores, aid_pairs.T), shape=(N, N)) csgraph.connected_components(mat) tree = csgraph.minimum_spanning_tree(mat) # NOQA import plottool as pt dense = mat.todense() pt.imshow(dense / dense.max() * 255) pt.show_if_requested() # baseline jobid import opengm # https://github.com/opengm/opengm/blob/master/src/interfaces/python/examples/tutorial/OpenGM%20tutorial.ipynb numVar = 10 unaries = np.ones([numVar, 3], dtype=opengm.value_type) gm = opengm.gm(np.ones(numVar, dtype=opengm.label_type) * 3) unary_fids = gm.addFunctions(unaries) gm.addFactors(unary_fids, np.arange(numVar)) infParam = opengm.InfParam( workflow=ut.ensure_ascii('(IC)(TTC-I,CC-I)'), ) inf = opengm.inference.Multicut(gm, parameter=infParam) visitor = inf.verboseVisitor(printNth=1, multiline=False) inf.infer(visitor) arg = inf.arg() # gridVariableIndices = opengm.secondOrderGridVis(img.shape[0], img.shape[1]) # fid = gm.addFunction(regularizer) # gm.addFactors(fid, gridVariableIndices) # regularizer = opengm.pottsFunction([3, 3], 0.0, beta) # gridVariableIndices = opengm.secondOrderGridVis(img.shape[0], img.shape[1]) # fid = gm.addFunction(regularizer) # gm.addFactors(fid, gridVariableIndices) unaries = np.random.rand(10, 10, 2) potts = opengm.PottsFunction([2, 2], 0.0, 0.4) gm = opengm.grid2d2Order(unaries=unaries, regularizer=potts) inf = opengm.inference.GraphCut(gm) inf.infer() arg = inf.arg() # NOQA """
def make_random_trees(n_samples=50, n_nodes=100, n_states=7, n_features=10): crf = GraphCRF(inference_method='max-product', n_states=n_states, n_features=n_features) weights = np.random.randn(crf.size_joint_feature) X, y = [], [] for i in range(n_samples): distances = np.random.randn(n_nodes, n_nodes) features = np.random.randn(n_nodes, n_features) tree = minimum_spanning_tree(sparse.csr_matrix(distances)) edges = np.c_[tree.nonzero()] X.append((features, edges)) y.append(crf.inference(X[-1], weights)) return X, y, weights
def cf(self): # Create a minimum spanning Tree of Graph G Tcsr = minimum_spanning_tree(self.adjMatrix) MSTedges = [] degreeDict = dict( zip(self.nodeDict.keys(), [0] * len(self.nodeDict.keys()))) Z = Tcsr.toarray().astype(float) for i in range(len(Z)): array = np.nonzero(Z[i])[0] for index in array: if index.size != 0: degreeDict[i] += 1 degreeDict[index] += 1 tuplex = (i, index) MSTedges.append(tuplex) # STEP 2: Isolate the vertices of the MST with odd degree OddVerts = [x for x in degreeDict.keys() if degreeDict[x] % 2 != 0] # STEP 3: Only Consider the values in OddVerts and form a min-weight perfect matching H = nx.Graph() H.add_nodes_from(self.nodeDict.keys()) for i in range(len(OddVerts)): for j in range(len(OddVerts)): if i != j: H.add_edge( OddVerts[i], OddVerts[j], weight=-self.adjMatrix[OddVerts[i]][OddVerts[j]]) minWeight = list(naa.max_weight_matching(H, maxcardinality=True)) uniqueMW = [] # Prune out redundant Tuples for edge in minWeight: if edge not in uniqueMW and (edge[1], edge[0]) not in uniqueMW: uniqueMW.append(edge) unionMW_MST = MSTedges[:] for tup in uniqueMW: # Only add first index since both edges are returned for instance: (0,1) & (1,0) are returned unionMW_MST.append(tup) degreeDict[tup[0]] += 1 degreeDict[tup[1]] += 1 # Retrieve the Eulerian Circuit eulerianCircuit = self.eulerianTour(unionMW_MST, self.nodeDict) shortCut = [] unvisitedPath = [] totalPath = [i for sub in eulerianCircuit for i in sub] for node in totalPath: if node not in unvisitedPath: shortCut.append(node) unvisitedPath.append(node) return [MSTedges, minWeight, eulerianCircuit, self.pathEdges(shortCut)]
def intra_encounter_matching(): import numpy as np from scipy.sparse import coo_matrix, csgraph qreq_, cm_list = testdata_workflow() # qaids = [cm.qaid for cm in cm_list] # top_aids = [cm.get_top_aids(5) for cm in cm_list] aid_pairs = np.array([(cm.qaid, daid) for cm in cm_list for daid in cm.get_top_aids(5)]) top_scores = ut.flatten([cm.get_top_scores(5) for cm in cm_list]) N = aid_pairs.max() + 1 mat = coo_matrix((top_scores, aid_pairs.T), shape=(N, N)) csgraph.connected_components(mat) tree = csgraph.minimum_spanning_tree(mat) # NOQA import plottool as pt dense = mat.todense() pt.imshow(dense / dense.max() * 255) pt.show_if_requested() # baseline jobid import opengm # https://github.com/opengm/opengm/blob/master/src/interfaces/python/examples/tutorial/OpenGM%20tutorial.ipynb numVar = 10 unaries = np.ones([numVar, 3], dtype=opengm.value_type) gm = opengm.gm(np.ones(numVar, dtype=opengm.label_type) * 3) unary_fids = gm.addFunctions(unaries) gm.addFactors(unary_fids, np.arange(numVar)) infParam = opengm.InfParam(workflow=ut.ensure_ascii('(IC)(TTC-I,CC-I)'), ) inf = opengm.inference.Multicut(gm, parameter=infParam) visitor = inf.verboseVisitor(printNth=1, multiline=False) inf.infer(visitor) arg = inf.arg() # gridVariableIndices = opengm.secondOrderGridVis(img.shape[0], img.shape[1]) # fid = gm.addFunction(regularizer) # gm.addFactors(fid, gridVariableIndices) # regularizer = opengm.pottsFunction([3, 3], 0.0, beta) # gridVariableIndices = opengm.secondOrderGridVis(img.shape[0], img.shape[1]) # fid = gm.addFunction(regularizer) # gm.addFactors(fid, gridVariableIndices) unaries = np.random.rand(10, 10, 2) potts = opengm.PottsFunction([2, 2], 0.0, 0.4) gm = opengm.grid2d2Order(unaries=unaries, regularizer=potts) inf = opengm.inference.GraphCut(gm) inf.infer() arg = inf.arg() # NOQA """
def RegularControl(network,numNodes): matrix = [[0 for x in range(numNodes)] for x in range(numNodes)] for col in range(0,numNodes): for row in range(0,col+1): matrix[row][col] = network[row][col] minTree = minimum_spanning_tree(matrix).toarray().astype(int) minPower = np.amax(minTree) transfers = [] for col in range(0,numNodes): for row in range(col+1, numNodes): matrix[row][col] = network[col][row] if network[row][col] != 0: if network[row][col] == 1: transfers.append([row, col]) else: transfers.append([col, row]) noise = [] for row in transfers: if matrix[row[0]][row[1]] <= minPower: if row[1] not in noise: noise.append(row[1]) else: path = GeneratePaths(matrix, minPower, row[0], row[1], numNodes) for x in range (1, len(path)): if path[x] not in noise: noise.append(path[x]) for row in transfers: noiseDist = [] for node in noise: if node == row[1]: continue else: noiseDist.append(1/float(matrix[node][row[1]])) if sum(noiseDist) == 0: totalNoise = 1 else: totalNoise = 1/sum(noiseDist) if totalNoise < 1: return -1 return 1
def get_mst_sequence(self): """Finds the minimum spanning tree sequence for the low-confidence voxels in the patch around the seed. The dimensions of the patch are defined by the patch length parameter.""" iflat = self.intensity.ravel() #fill the weight matrix for the MST n = np.shape(self.lcvp)[0] #the number of lcv in the patch weightm = np.zeros((n, n)) for wx in range(0, n): for wy in range(wx, n): if self.lcvp[wx] in self.neighbors_small[self.lcvp[wy]]: weightm[wx][wy] = abs( iflat[self.lcvp[wx]] - iflat[self.lcvp[wy]]) #intensity gradient else: xcoord = np.asarray( np.unravel_index(self.lcvp[wx], self.labels.shape)) ycoord = np.asarray( np.unravel_index(self.lcvp[wy], self.labels.shape)) weightm[wx][wy] = 100 * np.linalg.norm( xcoord - ycoord) #proportional to the norm mst = csgraph.minimum_spanning_tree(weightm).toarray() #get the MST #find the MST sequence self.seq = [np.argwhere(self.lcvp == self.seeds[0])[0][0]] edges = np.argwhere(mst).tolist() #edges of the MST while edges: mincost = np.amax(mst) + 1 for e in edges: if (e[0] in self.seq or e[1] in self.seq) and mst[e[0]][e[1]] < mincost: mincost = mst[e[0]][e[1]] nextedge = e #find the edge with minimum cost if nextedge[0] in self.seq: self.seq.append(nextedge[1]) else: #if nextedge[1] in self.seq self.seq.append(nextedge[0]) edges.remove(nextedge) self.seq = [self.lcvp[i] for i in self.seq] #get the ordered list of lcv del self.seeds[0]
def _single_linkage_tree(connectivity, n_samples, n_nodes, n_clusters, n_connected_components, return_distance): """ Perform single linkage clustering on sparse data via the minimum spanning tree from scipy.sparse.csgraph, then using union-find to label. The parent array is then generated by walking through the tree. """ from scipy.sparse.csgraph import minimum_spanning_tree # explicitly cast connectivity to ensure safety connectivity = connectivity.astype('float64', **_astype_copy_false(connectivity)) # Ensure zero distances aren't ignored by setting them to "epsilon" epsilon_value = np.finfo(dtype=connectivity.data.dtype).eps connectivity.data[connectivity.data == 0] = epsilon_value # Use scipy.sparse.csgraph to generate a minimum spanning tree mst = minimum_spanning_tree(connectivity.tocsr()) # Convert the graph to scipy.cluster.hierarchy array format mst = mst.tocoo() # Undo the epsilon values mst.data[mst.data == epsilon_value] = 0 mst_array = np.vstack([mst.row, mst.col, mst.data]).T # Sort edges of the min_spanning_tree by weight mst_array = mst_array[np.argsort(mst_array.T[2]), :] # Convert edge list into standard hierarchical clustering format single_linkage_tree = _hierarchical._single_linkage_label(mst_array) children_ = single_linkage_tree[:, :2].astype(np.int) # Compute parents parent = np.arange(n_nodes, dtype=np.intp) for i, (left, right) in enumerate(children_, n_samples): if n_clusters is not None and i >= n_nodes: break if left < n_nodes: parent[left] = i if right < n_nodes: parent[right] = i if return_distance: distances = single_linkage_tree[:, 2] return children_, n_connected_components, n_samples, parent, distances return children_, n_connected_components, n_samples, parent
def streaming_spanning_tree_v1(streaming_generator, return_img=False): r""" Function that implement our first streaming version of minimum spanning tree Parameters ---------- streaming_generator: generator Generator of the streaming At each iteration it should yield: - the ith block of the image - the graph associated to the ith block of image - the root id of the graph - the ids of the vertices in the common border with the graph in the next iteration return_img: bool (default False) If true the method yields also ith image int the generator otherwise no. """ old_e = None old_root = None old_front = None for img, graph, root, front in streaming_generator: t = minimum_spanning_tree(graph) if old_e is None: # first iteration old_e = get_half_cycle(t, root, front) t = t - old_e old_root = root old_front = front if return_img: yield t, old_e, img else: yield t, old_e else: # we assume that the size of the graph increases during the iterations old_e = resize_graph(old_e, graph.shape) t, e = _update_minimum_spanning_tree(t, old_e, old_front, old_root, front, root) # updating variables for next iteration old_e = e old_front = front old_root = root if return_img: yield t, old_e, img else: yield t, e
def mkNN(X, k, measure='euclidean'): """ Construct mutual_kNN for large scale dataset If j is one of i's closest neighbors and i is also one of j's closest members, the edge will appear once with (i,j) where i < j. Parameters ---------- X : [n_samples, n_dim] array k : int number of neighbors for each sample in X """ from scipy.spatial import distance from scipy.sparse import csr_matrix, triu, find from scipy.sparse.csgraph import minimum_spanning_tree samples = X.shape[0] batchsize = 10000 b = np.arange(k+1) b = tuple(b[1:].ravel()) z=np.zeros((samples,k)) weigh=np.zeros_like(z) # This loop speeds up the computation by operating in batches # This can be parallelized to further utilize CPU/GPU resource for x in np.arange(0, samples, batchsize): start = x end = min(x+batchsize,samples) w = distance.cdist(X[start:end], X, measure) y = np.argpartition(w, b, axis=1) z[start:end,:] = y[:, 1:k + 1] weigh[start:end,:] = np.reshape(w[tuple(np.repeat(np.arange(end-start), k)), tuple(y[:, 1:k+1].ravel())], (end-start, k)) del(w) ind = np.repeat(np.arange(samples), k) P = csr_matrix((np.ones((samples*k)), (ind.ravel(), z.ravel())), shape=(samples,samples)) Q = csr_matrix((weigh.ravel(), (ind.ravel(), z.ravel())), shape=(samples,samples)) Tcsr = minimum_spanning_tree(Q) P = P.minimum(P.transpose()) + Tcsr.maximum(Tcsr.transpose()) P = triu(P, k=1) return np.asarray(find(P)).T
def train_weighted(self, weights, data): # weights is a np vector assigning weights to every data-vector in data N = data.shape[0] alpha = max(np.sum(weights), 1) alpha /= N pairwise_counts = utils.compute_pairwise_counts_weighted(data, weights) + alpha self.prob_pair = utils.normalize2D(pairwise_counts) single_counts = utils.compute_single_counts_weighted(data, weights) + 2 * alpha self.prob_sing = utils.normalize1D(single_counts) adjmat = utils.compute_adjmatrix(self.prob_pair, self.prob_sing) adjmat *= -1.0 # making negative for MST calc adjmat[adjmat == 0.0] = 1e-10 mstree = minimum_spanning_tree(csr_matrix(adjmat)) self.node_order, self.parent = depth_first_order(mstree, 0, directed=False)
def build_graph(X, graph_type='knn-mst', n_neighbors=5, mst_weight=1): if graph_type == 'complete': d = pdist(X) A = squareform(d) elif graph_type == 'knn': A = kneighbors_graph(X, n_neighbors, 'distance').toarray() A = (A + A.T) / 2 elif graph_type == 'knn-mst': A = kneighbors_graph(X, n_neighbors, 'distance').toarray() A = (A + A.T) / 2 D = squareform(pdist(X)) MST = minimum_spanning_tree(D).toarray() MST = (MST + MST.T) / 2 A = np.maximum(A, MST * mst_weight) elif graph_type == 'mst': D = squareform(pdist(X)) A = minimum_spanning_tree(D).toarray() A = A + A.T return A
def _build_mst(self, config, fully_matrix): mst_file_name = os.path.join(self.outdir_tsp_mst, config["name"] + ".txt") with open(mst_file_name, "w") as outfile: # header : node_count edge_count outfile.write("%d %d" % (config["node_count"], config["node_count"] - 1)) # build mst tcsr_arr = minimum_spanning_tree( csr_matrix(fully_matrix)).toarray().astype(int) # contents : start_node end_node weight for row_idx, row in enumerate(tcsr_arr): for col_idx, item in enumerate(row): if item: outfile.write("\n%d %d %d" % (row_idx, col_idx, item))
def mst(points): p1 = points[0] n = len(points) dist_matrix = csr_matrix((n,n),dtype=np.float) for i in range(n-1): for j in range(i,n): dist_matrix[i,j] = dist(points[i],points[j]) Tcsr = minimum_spanning_tree(dist_matrix) val = np.max(Tcsr.toarray()) return val
def get_tree(A): A=A.tocsc() degree=A.sum(0).getA1() Adata=A.data Aindices=A.indices Aindptr=A.indptr n=A.shape[0] for i in range(0,n): for j in range(Aindptr[i],Aindptr[i+1]): Adata[j]=degree[Aindices[j]]+degree[i] T=-minimum_spanning_tree(-A) return T
def _get_connectivities_tree_v1_0(self, inter_es): inverse_inter_es = inter_es.copy() inverse_inter_es.data = 1. / inverse_inter_es.data connectivities_tree = minimum_spanning_tree(inverse_inter_es) connectivities_tree_indices = [ connectivities_tree[i].nonzero()[1] for i in range(connectivities_tree.shape[0]) ] connectivities_tree = sp.sparse.lil_matrix(inter_es.shape, dtype=float) for i, neighbors in enumerate(connectivities_tree_indices): if len(neighbors) > 0: connectivities_tree[i, neighbors] = self.connectivities[i, neighbors] return connectivities_tree.tocsr()
def mutual_reach_dist_MST(self, X): dists = pairwise_distances(X, X, metric=self.metric) mutual_reachaility = np.empty((dists.shape)) graph = np.empty(dists.shape) for rownum in np.arange(0, dists.shape[0]): row = dists[rownum, :] i_core = np.empty(dists.shape[0]) i_core.fill(self.core_distances_[rownum]) j_core = self.core_distances_.ravel() npmut = np.vstack((row, i_core, j_core)) r = np.amax(npmut, axis=0) graph[rownum, :] = r mst_ = minimum_spanning_tree(graph).toarray() mst = mst_ + np.transpose(mst_) return mst
def test_min_distance_speed(): test_logger.critical('\n' + sys._getframe().f_code.co_name + '\n') x_list, y_list = read_data() start = time.time() my_dist = MST.minimum_distance(x_list, y_list) finished = time.time() assert finished - start < 10 points = MST.convert_to_np_points(x_list, y_list) dist = MST.calculate_distances(points) dist = csr_matrix(np.triu(dist)) Tcsr = minimum_spanning_tree(dist) assert my_dist == pytest.approx(Tcsr.toarray().sum()) test_logger.critical('\n' + sys._getframe().f_code.co_name + '\n')
def calculate_max_spanning_tree_genotype(self): ''' Compute the genotype of the maximum spanning tree of the instance. ''' max_spanning_tree = minimum_spanning_tree( self.fast_fit * -1).toarray().astype(np.int) < 0 max_spanning_tree += max_spanning_tree.transpose() first_index = np.unravel_index(np.argmax(max_spanning_tree), max_spanning_tree.shape) return self.calculate_genotype_from_start_node(first_index[0], max_spanning_tree)
def get_parse_layout(self,adj_matrix,dict_mapping_Symbol_index,index_to_symbol,rel_classifier_obj): ''' The function returns a dictionary of relation corresponding to two symbols, which is later used for writing it to a lg files. ''' symbol_obj=Symbol() dict_map_rel_to_syms={} tree=minimum_spanning_tree(adj_matrix) mst=tree.toarray() for i in xrange(mst.shape[0]): eye_obj=index_to_symbol[i] arr=np.where(mst[i]>0)[0] if arr.shape[0]==0: continue else: trace_list=[] points_eye=[] for k in xrange(len(eye_obj.symbol_list)): points_eye+=eye_obj.symbol_list[k].original_points for j in xrange(arr.shape[0]): other_obj=index_to_symbol[arr[j]] total_points=[] for l in xrange(len(other_obj.symbol_list)): total_points+=other_obj.symbol_list[l].original_points total_points=points_eye+total_points trace_obj=Trace(points_float=total_points) trace_obj.normalization() trace_list.append(trace_obj) symbol_obj.symbol_list=trace_list features=symbol_obj.get_features() X_test=np.asarray(features) label=rel_classifier_obj.predict(X_test.reshape(1,-1)) if label[0] not in dict_map_rel_to_syms: dict_map_rel_to_syms[label[0]] = [] dict_map_rel_to_syms[label[0]].append((eye_obj,other_obj)) else: dict_map_rel_to_syms[label[0]].append((eye_obj,other_obj) ) trace_list.remove(trace_obj) return dict_map_rel_to_syms,
def foodHeuristic(state, problem): """ Your heuristic for the FoodSearchProblem goes here. This heuristic must be consistent to ensure correctness. First, try to come up with an admissible heuristic; almost all admissible heuristics will be consistent as well. If using A* ever finds a solution that is worse uniform cost search finds, your heuristic is *not* consistent, and probably not admissible! On the other hand, inadmissible or inconsistent heuristics may find optimal solutions, so be careful. The state is a tuple ( pacmanPosition, foodGrid ) where foodGrid is a Grid (see game.py) of either True or False. You can call foodGrid.asList() to get a list of food coordinates instead. If you want access to info like walls, capsules, etc., you can query the problem. For example, problem.walls gives you a Grid of where the walls are. If you want to *store* information to be reused in other calls to the heuristic, there is a dictionary called problem.heuristicInfo that you can use. For example, if you only want to count the walls once and store that value, try: problem.heuristicInfo['wallCount'] = problem.walls.count() Subsequent calls to this heuristic can access problem.heuristicInfo['wallCount'] """ def euclideanDistance(xy1,xy2): """ The Euclidean distance between two points xy1 and xy2 in R^2 """ return ( (xy1[0] - xy2[0]) ** 2 + (xy1[1] - xy2[1]) ** 2 ) ** 0.5 def make_graph(posList): """ Build an undirected graph over the set of coordinates contained in posList. """ distMatrix = [[0 for i in range(len(posList))] for j in range(len(posList))] for i in range(len(posList)): for j in range(i, len(posList)): distMatrix[i][j] = euclideanDistance(posList[i], posList[j]) return csr_matrix(distMatrix) position, foodGrid = state positions = foodGrid.asList() + [position] # Return the cost of the minimum spanning tree mst = minimum_spanning_tree(make_graph(positions)).toarray().astype(float) return mst.sum()
def _update_minimum_spanning_tree(t_new, e_old, front_old, root_old, front_new=None, root_new=-1): """Function that compute the nth iteration of minimum spanning tree algorithm for images Parameters ---------- t_new: csr_matrix MST of the newly arrived graph e_old: csr_matrix Edges in the old tree that are supposed to form cycles front_old: ndarray Frontier of the newly arrived graph with the old graph root_old: int id of the node used as root in the previous iteration front_new: ndarray Frontier of the newly arrived graph with further graph root_new: int ID of the node that we are going to use as root in this iteration """ # find edges that form cycles in the fusion between the fusion of two mst e_new = get_half_cycle(t_new, root_old, front_old) # removing from new_t the edges that form cycles t_new = t_new - e_new # the cycles the merged graph are defined by the maximum between e_old and e_new e_in_cycles = merge_graphs([e_old, e_new]) # computing the mst we remove all the cycles in e_in_cycles mst_e_in_cycles = minimum_spanning_tree(e_in_cycles) t_n = t_new + mst_e_in_cycles if front_new is not None: # computing edges in cycles for the next iteration e_n = get_half_cycle(t_n, root_new, front_new) return t_n - e_n, e_n # we always return two elements return t_n, None
def eval_node_probs(self): """Update probability density estimates. """ # Create mutual info matrix mutual_info = np.zeros([self.length, self.length]) for i in range(self.length - 1): for j in range(i + 1, self.length): # DEBUGGING CODE try: mutual_info[i, j] = -1 * mutual_info_score( self.keep_sample[:, i], self.keep_sample[:, j]) except ValueError: print(f'self.keep_sample[:, i] = {self.keep_sample[:, i]}') print(f'self.keep_sample[:, j] = {self.keep_sample[:, j]}') raise Exception("Caught value error") # Find minimum spanning tree of mutual info matrix mst = minimum_spanning_tree(csr_matrix(mutual_info)) # Convert minimum spanning tree to depth first tree with node 0 as root dft = depth_first_tree(csr_matrix(mst.toarray()), 0, directed=False) dft = np.round(dft.toarray(), 10) # Determine parent of each node parent = np.argmin(dft[:, 1:], axis=0) # Get probs probs = np.zeros([self.length, self.max_val, self.max_val]) probs[0, :] = np.histogram(self.keep_sample[:, 0], np.arange(self.max_val + 1), density=True)[0] for i in range(1, self.length): for j in range(self.max_val): subset = self.keep_sample[np.where( self.keep_sample[:, parent[i - 1]] == j)[0]] if not len(subset): probs[i, j] = 1 / self.max_val else: probs[i, j] = np.histogram(subset[:, i], np.arange(self.max_val + 1), density=True)[0] # Update probs and parent self.node_probs = probs self.parent_nodes = parent
def minimumSpanningTree(self, vectors): #input shape: nxdim #output: nxn numpy array with the minimum spanning tree #sparse upper matrix-all nonzero entries represent edges in the MST #creates a graph with the distances to all of the vectors distances, pairs = self.distance_function(vectors) distances[distances == 0] = 10**-38 graph = self.construct_graph(len(vectors), distances, pairs) #uses the scipy csr_matrix and minimum_spanning_tree commands to create the tree graph = csr_matrix(graph) Tcsr = minimum_spanning_tree(graph) Tcsr = Tcsr.toarray() return (Tcsr)
def MST(dis, Q_index): dis = dis[:, Q_index] d = csr_matrix(dis.astype('float')) Tcsr = minimum_spanning_tree(d) del d mpn = Tcsr.toarray().astype(float) del Tcsr mpn[mpn != 0] = 1 n = dis.shape[0] for i in range(n): for j in range(n): if mpn[i, j] != 0: mpn[j, i] = 1 return mpn
def learnStructure(self, dataset): self.nvariables = dataset.shape[1] self.xycounts = Util.compute_xycounts(dataset) + 1 # laplace correction self.xcounts = Util.compute_xcounts(dataset) + 2 # laplace correction self.xyprob = Util.normalize2d(self.xycounts) self.xprob = Util.normalize1d(self.xcounts) # compute mutual information score for all pairs of variables # weights are multiplied by -1.0 because we compute the minimum spanning tree edgemat = Util.compute_edge_weights(self.xycounts, self.xcounts) * (-1.0) edgemat[edgemat == 0.0] = 1e-20 # sha1225 # to avoid tree not connected # compute the minimum spanning tree Tree = minimum_spanning_tree(csr_matrix(edgemat)) # Convert the spanning tree to a Bayesian network self.topo_order, self.parents = depth_first_order(Tree, 0, directed=False) #self.Tree = Tree self.get_log_cond_cpt()
def calculateMSTUpperBound(self): mst = minimum_spanning_tree(self.adjMatrix) MSTedges = [] Z = mst.toarray().astype(float) for i in range(len(Z)): array = np.nonzero(Z[i])[0] for index in array: tuplex = (i, index) MSTedges.append(tuplex) cost = 0 for edge in MSTedges: checkEdge = edge if (checkEdge not in self.edgeDict): checkEdge = (edge[1], edge[0]) cost += self.edgeDict[checkEdge] return 2 * cost
def mst_edges(V, k): """ Construct the approximate minimum spanning tree from vectors V :param: V: 2D array, sequence of vectors :param: k: int the number of neighbor to consider for each vector :return: V ndarray of edges forming the MST """ # k = len(X)-1 gives the exact MST k = min(len(V) - 1, k) # generate a sparse graph using the k nearest neighbors of each point G = kneighbors_graph(V, n_neighbors=k, mode='distance') # Compute the minimum spanning tree of this graph full_tree = minimum_spanning_tree(G, overwrite=True) return np.array(full_tree.nonzero()).T
def sync_perm_mat(match_perms_all, match_cost, n_atoms): tree = minimum_spanning_tree(match_cost, overwrite=True) perms = np.arange(n_atoms, dtype=int)[None, :] rows, cols = tree.nonzero() for com in zip(rows, cols): perm = match_perms_all.get(com) if perm is not None: perms = np.vstack((perms, perm)) perms = np.unique(perms, axis=0) ui.progr_toggle( is_done=True, disp_str='Multi-partite matching (permutation synchronization)') return perms
def __init__(self, N): self.N = N MAX_DIST = 50 distance = np.random.random_integers(0, MAX_DIST,size=(N,N)) self.distance = (distance + distance.T)/2 # self.distance = distance - np.diag(distance.diagonal()) self.ub = N*N * np.max(distance) # Calls the initializer (constructor) of the class 'search_space' self.search_space = EdgeSpace(self.N) self.sol = minimum_spanning_tree(self.distance) self.adjmat = self.sol.toarray().astype(int) self.ref = np.sum(self.adjmat)
def learnStructure_prob(self, p_xy, p_x): self.nvariables = p_x.shape[0] self.xyprob = p_xy self.xprob = p_x # compute mutual information score for all pairs of variables # weights are multiplied by -1.0 because we compute the minimum spanning tree edgemat = Util.compute_MI_prob(self.xyprob, self.xprob) * (-1.0) edgemat[edgemat == 0.0] = 1e-20 # sha1225 # to avoid tree not connected # compute the minimum spanning tree Tree = minimum_spanning_tree(csr_matrix(edgemat)) # Convert the spanning tree to a Bayesian network self.topo_order, self.parents = depth_first_order(Tree, 0, directed=False) self.get_log_cond_cpt()
def chowliu_tree(pdata): ''' generate chow-liu tree. Args: pdata (1darray): empirical distribution in dataset Returns: list: entangle pairs. ''' X = mutual_information(pdata) Tcsr = -minimum_spanning_tree(-X) Tcoo = Tcsr.tocoo() pairs = list(zip(Tcoo.row, Tcoo.col)) print('Chow-Liu tree pairs = %s' % pairs) return pairs
def calculate_MST(Xpred, Xtruth): """ Function to calculate the MST for both Xpred and Xtruth under using the segmentation of 0.01 """ MST_list = np.zeros([2, 4]) X_list = [Xpred, Xtruth] for cnt, X in enumerate(X_list): for i in range(4): points = X[:, i:i + 5:4] distance_matrix_points = distance_matrix(points, points, p=2) csr_mat = csr_matrix(distance_matrix_points) Tree = minimum_spanning_tree(csr_mat) MST_list[cnt, i] = np.sum(Tree.toarray().astype(float)) X_MST = np.mean(MST_list, axis=1) return X_MST[0], X_MST[1]
def _mutual_reach_dist_MST(dist_tree): """ Computes minimum spanning tree of the mutual reach distance complete graph Args: dist_tree (np.ndarray): array of dimensions (n_samples, n_samples) Graph of all pair-wise mutual reachability distances between points. Returns: minimum_spanning_tree (np.ndarray) array of dimensions (n_samples, n_samples) minimum spanning tree of all pair-wise mutual reachability distances between points. """ mst = minimum_spanning_tree(dist_tree).toarray() return mst + np.transpose(mst)
def __init__(self, r, make_com=True): """ Subroutine: build Euclidean minimum spanning tree from points Arguments --------- r[:,:]: float array of point positions [n_points:n_dim] make_com: boolean also generate complete graph (may be very large) """ # Calculate Delaunay triangulation print("Generating Delaunay triangulation.") self.r = r self.del_tri = Delaunay(self.r) # Convert Delaunay triangulation to matrix graph format print("Converting triangulation to sparse matrix format.") self.tri = lil_matrix((r.shape[0], r.shape[0]), dtype=r.dtype) indices = self.del_tri.vertex_neighbor_vertices[0] indptr = self.del_tri.vertex_neighbor_vertices[1] # loop over all points for i in range(self.r.shape[0]): # loop over all neighbours of each point for j in indptr[indices[i]:indices[i + 1]]: # only populate upper portion of del_tri if j > i: # calculate edge weight of graph l = np.linalg.norm(self.r[i, :] - self.r[j, :]) self.tri[i, j] = l # convert to csr format self.tri = self.tri.tocsr() # Calculate minimum spanning tree print("Generating minimum spanning tree.") self.mst = minimum_spanning_tree(self.tri) if make_com: distances = squareform(pdist(r)) self.com = csr_matrix(distances) print("All graphs generated.")
def mst(adjMat): """ Find the minimum spanning tree of a graph defined by adjacency matrix. Parameters ---------- `adjMat` : scipy sparse matrix adjacency matrix of a graph Returns ------- `adjMat_of_mst` : scipy sparse matrix adjacency matrix of minimum spanning tree of the graph """ adjMat_of_mst = minimum_spanning_tree(adjMat) return adjMat_of_mst
def reduce_coordination(target, z): r""" Deletes throats on network to match specified average coordination number Parameters ---------- target : GenericNetwork The network whose throats are to be trimmed z : scalar The desired average coordination number. It is not possible to specify the distribution of the coordination, only the mean value. Returns ------- trim : ndarray A boolean array with ``True`` values indicating which pores to trim (using ``op.topotools.trim``) to obtain the desired average coordination number. Notes ----- This method first finds the minimum spanning tree of the network using random weights on each throat, then assures that these throats are *not* deleted, in order to maintain network connectivity. The list of throats to trim is generated randomly from the throats *not* on the spanning tree. """ network = target # Find minimum spanning tree using random weights am = network.create_adjacency_matrix(weights=np.random.rand(network.Nt), triu=False) mst = csgraph.minimum_spanning_tree(am, overwrite=True) mst = mst.tocoo() # Label throats on spanning tree to avoid deleting them Ts = network.find_connecting_throat(mst.row, mst.col) Ts = np.hstack(Ts) network['throat.mst'] = False network['throat.mst'][Ts] = True # Trim throats not on the spanning tree to acheive desired coordination Ts = np.random.permutation(network.throats('mst', mode='nor')) del network['throat.mst'] Ts = Ts[:int(network.Nt - network.Np*(z/2))] Ts = network.to_mask(throats=Ts) return Ts