def triangulate(self, C, randomized=False): ''' Find a minimum triangulation of a graph Args: C : a graph in networkx format randomized : has no effect Return: F : a set of edges such that C + F is a minimum triangulation ''' logging.info("=== MT.triangulate ===") if nx.is_chordal(C): logging.debug("Component is already chordal") return [] # use LEX-M to determine the size of a minimal triangulation to have an upper bound for the minimum triangulation lexm_triang = LEX_M.triangulate_LexM(C) size_minimal = lexm_triang["size"] logging.debug("size of minimal: "+str(size_minimal)) F = [] # iterate through all subsets of chord edges by increasing set size. # for each subset, check if self.G + additional edges is chordal # return first set of edges that makes self.G chordal. this is a minimum triangulation. k = 1 found_minimum = False #print (self.chordedge_candidates) while not found_minimum and k < size_minimal: # check timeout: if self.timeout > 0 and time.time() > self.timeout: raise ta.TimeLimitExceededException("Time Limit Exceeded!") logging.debug("Current iteration: consider edgesets of size "+str(k)) edgesets_size_k = itertools.combinations(self.chordedge_candidates, k) k_edgeset = 0 for edgeset in edgesets_size_k: #print (edgeset) k_edgeset += 1 if k_edgeset%10000 == 0: # check timeout every 10k sets: if self.timeout > 0 and time.time() > self.timeout: raise ta.TimeLimitExceededException("Time Limit Exceeded!") H = C.copy() H.add_edges_from(edgeset) if nx.is_chordal(H): F += [e for e in edgeset] found_minimum = True break k += 1 if not found_minimum: F += [e for e in lexm_triang["H"].edges() if e not in C.edges()] return F
def is_chordal(edge_list): """ Check if the graph is chordal/triangulated. Parameters ---------- *edge_list* : a list of lists (optional) The edges to check (if not self.E) Returns ------- *nx.is_chordal(G)* : a boolean Whether the graph is chordal or not Effects ------- None Notes ----- Again, do we need networkx for this? Eventually should write this check on our own. """ G = nx.Graph(list(edge_list)) return nx.is_chordal(G)
def test_logmu_monte_carlo(): p = 4 matspace = [range(2) for i in range(p * p)] graphs = {} graph_jtreps = {} for adjmatvec in itertools.product(*matspace): adjmat = np.matrix(adjmatvec).reshape(p, p) if np.diag(adjmat).sum() == 0: g = nx.from_numpy_matrix(adjmat) if nx.is_chordal(g): if check_symmetric(adjmat): # print libg.mu(g) graphs[adjmatvec] = trilearn.graph.decomposable.n_junction_trees(g) jt = trilearn.graph.decomposable.junction_tree(g) S = jt.get_separators() graph_jtreps[adjmatvec] = {"graph": g, "jts": set(), "mu": np.exp(jtlib.log_n_junction_trees(jt, S))} for i in range(100): jtlib.randomize(jt) graph_jtreps[adjmatvec]["jts"].add(jt.tuple()) #print graphs #print "Exact number of chordal graphs: " + str(len(graph_jtreps)) #print "Exact number of junction trees: " + str(np.sum([val for key, val in graphs.iteritems()])) sum = 0 for graph, val in graph_jtreps.items(): #print val["mu"], val["jts"] #print val["mu"] - len(val["jts"]) sum += len(val["jts"]) assert np.abs(val["mu"] - len(val["jts"]) < 0.0000001) print(sum)
def addMoreEdges(self, requiredMoreEdges): """function to add more edges in the graph: moreEdges = givenEdges - treeEdges""" newEdges = 0 self.chordalGraph = copy.deepcopy(self.chordalTree) while newEdges < requiredMoreEdges: vertices = random.sample(self.chordalGraph, 2) u = vertices[0] v = vertices[1] if self.ifEdgeExist(self.chordalGraph, u, v): continue else: I_uv = list( set(self.chordalGraph[u]).intersection( self.chordalGraph[v])) if I_uv: x = random.choice(I_uv) auxNodes = list(set(self.chordalGraph[x]).difference(I_uv)) auxGraph = self.createAuxGraph(self.chordalGraph, auxNodes) if not self.isReachable(auxGraph, u, v): self.addAnEdge(self.chordalGraph, u, v) #print "Add edge between: "+str(u)+" and "+str(v) newEdges += 1 print self.chordalGraph G = nx.Graph(self.chordalGraph) if nx.is_chordal(G): print "========================" print "This is a Chordal graph." print "========================"
def pairwise_score_TVD(self, graph): if not nx.is_chordal(graph): graph = utils.tools.triangulate(graph) # junction tree size size = 0 exceed = False for clique in nx.find_cliques(graph): temp_size = self.domain.project(clique).size() # if temp_size > self.config['max_clique_size'] or len(clique) > 15: if temp_size > self.config['max_clique_size']: # print(clique, 'clique size exceeds', temp_size) exceed = True size += temp_size if size > self.config['max_parameter_size']: # print('total clique size exceeds') exceed = True if exceed: return self.min_score, 0, size noisy_TVD = 0 for attr1, attr2 in graph.edges: noisy_TVD += utils.tools.dp_TVD(self.TVD_map, self.data, self.domain, [attr1, attr2], self.TVD_noise)[1] score = noisy_TVD - self.config['size_penalty'] * size score -= nx.number_connected_components( graph) * self.config['connectivity_penalty'] return score, noisy_TVD, size
def pairwise_score_MI(self, graph): if not nx.is_chordal(graph): graph = utils.tools.triangulate(graph) # junction tree size size = 0 for clique in nx.find_cliques(graph): temp_size = self.domain.project(clique).size() # if temp_size > self.config['max_clique_size'] or len(clique) > 15: if temp_size > self.config['max_clique_size']: # print(temp_size) return self.min_score, 0, size size += temp_size if size > self.config['max_parameter_size']: # print(size, '!') return self.min_score, 0, size noisy_MI = 0 for attr1, attr2 in graph.edges: noisy_MI += utils.tools.dp_mutual_info(self.MI_map, self.entropy_map, self.data, self.domain, [attr1, attr2], self.MI_noise)[1] score = noisy_MI - self.config['size_penalty'] * size score -= nx.number_connected_components( graph) * self.config['connectivity_penalty'] return score, noisy_MI, size
def test_triangulation_of_3_clique_maps_on_itself(self): m = np.ones((3, 3)) np.fill_diagonal(m, 0) g = nx.Graph(m) t = triangulate_variable_elimination(g) self.assertTrue((m == nx.to_numpy_array(t)).all()) self.assertTrue(nx.is_chordal(t))
def addMoreEdges(self, requiredMoreEdges): """function to create connected trampolines""" newEdges = 0 while newEdges < requiredMoreEdges: trampolines = random.sample(range(len(self.trampoAllNodes)),2) u = random.choice(self.trampoAllNodes[trampolines[0]]) v = random.choice(self.trampoAllNodes[trampolines[1]]) if self.ifEdgeExist(self.trampolinesConnected, u, v): continue else: I_uv = list(set(self.trampolinesConnected[u]).intersection(self.trampolinesConnected[v])) if I_uv: x = random.choice(I_uv) auxNodes = list(set(self.trampolinesConnected[x]).difference(I_uv)) auxGraph = self.createAuxGraph(self.trampolinesConnected, auxNodes) if not self.isReachable(auxGraph, u, v): self.addAnEdge(self.trampolinesConnected, u, v) print "Added edge between: "+str(u)+" and "+str(v) newEdges += 1 self.plotGraph(self.trampolinesConnected, "Connected Trampolines") print self.trampolinesConnected G = nx.Graph(self.trampolinesConnected) if not nx.is_chordal(G): print "============================" print "This is NOT a Chordal graph." print "============================" print str(newEdges)+" edges added to connect trampolines"
def naive_decomposable_graph(n): """ Naive implementation for generating a random decomposable graph. Note that this will only for for small numbers (~10) of n. Args: n (int): order of the samples graph. Returns: NetworkX graph: A decomposable graph. Example: >>> g = dlib.naive_decomposable_graph(4) >>> g.edges EdgeView([(0, 1), (0, 3)]) >>> g.nodes NodeView((0, 1, 2, 3)) """ m = np.zeros(n * n, dtype=int) m.resize(n, n) for i in range(n - 1): for j in range(i + 1, n): e = np.random.randint(2) m[i, j] = e m[j, i] = e graph = nx.from_numpy_matrix(m) while not nx.is_chordal(graph): for i in range(n - 1): for j in range(i + 1, n): e = np.random.randint(2) m[i, j] = e m[j, i] = e graph = nx.from_numpy_matrix(m) return graph
def triangulate_ig(g, debug=True): g_nx = ig_to_nx(g) g_nx, h_nx, F = triangulate_nx(g_nx, debug=debug) assert nx.is_chordal(h_nx) gc = g.copy() gc.add_edges(F) return gc
def is_triangulated(self): """ Just checks if the graph is triangulated Parameters ---------- See Also -------- maxCardinalitySearch Example -------- >>> from pgmpy.base import UndirectedGraph >>> G = UndirectedGraph([(0, 1), (0, 3), (0, 8), (1, 2), (1, 4), ... (1,8), (2, 4), (2, 6), (2, 7), (3, 8), ... (3, 9), (4, 7),(4, 8), (5, 8), (5, 9), ... (5, 10), (6, 7), (7, 10),(8, 10)]) >>> G.jt_techniques(2,False,True) 4 >>> G.is_triangulated() True """ ret = nx.is_chordal(self) return ret
def LB_Triang(self, vertexList, edgeList, graphToRecognize): """This function is implemented based on the algorithm LB-Triang from the paper "A WIDE-RANGE EFFICIENT ALGORITHM FOR MINIMAL TRIANGULATION" by Anne Berry for recognition chordal graphs and add edges (if necessary) by making each vertex LB-simplicial.""" # graphToRecognize = {0: [1, 4], 1:[0, 2], 2:[1, 3], 3:[2, 4], 4:[0, 3]} # vertexList, edgeList = self.createEdgeList(graphToRecognize) # random.shuffle(vertexList) vertexVisibility = [0] * len(vertexList) isChordal = False for v in vertexList: print("The vertex " + str(vertexList.index(v)) + "-" + str(v) + " is verifying...") openNeighbors = graphToRecognize[v] print("My openNeighbors is;", openNeighbors) closedNeighbors = copy.deepcopy(openNeighbors) closedNeighbors.append(v) print("Closed Neighb:", closedNeighbors) cNMinusE = list(set(vertexList).difference( set(closedNeighbors))) # V-S print("cNMinusE:", cNMinusE) eAddedCount = 0 if cNMinusE: VMinusSGraph = self.createAuxGraph(graphToRecognize, cNMinusE) # G(V-S) componentsOri = sorted( nx.connected_components(nx.Graph(VMinusSGraph))) print("Component(s) in the graph: " + str(componentsOri)) componentsCompAll = [] for co in componentsOri: openNCO = [] for v1 in co: openNV1 = graphToRecognize[v1] print("openNV1", openNV1) openNCO = openNCO + openNV1 print("pehle wala openNCO", openNCO) openNCO = list(set(openNCO).difference(co)) print("Baad wala openNCO:", openNCO) eCounter = self.createCompleteGraph(openNCO) # if eCounter >= 1: # self.plotGraph(self.H, str(eCounter)+" edge(s) added.") # print "================================================" # else: # print "================================================" else: print("The vertex " + str(v) + " does not generate any minimal separator.") print("================================================") ###For recognition, if the generated graph is a chordal graph or not. graph = nx.Graph(self.H) if nx.is_chordal(graph): print( "*********After adding edges the generated graph is Chordal graph.*********" ) else: print( "*********After adding edges the generated graph is NOT Chordal graph.*********" )
def test_triangulation_of_square_adds_one_edge(self): g = nx.Graph() g.add_nodes_from(range(4)) g.add_edges_from([(0, 1), (1, 2), (2, 3), (3, 0)]) t = triangulate_variable_elimination(g) self.assertTrue(t.number_of_edges() == 5) self.assertTrue(nx.is_chordal(t))
def test_is_chordal(self): assert not nx.is_chordal(self.non_chordal_G) assert nx.is_chordal(self.chordal_G) assert nx.is_chordal(self.connected_chordal_G) assert nx.is_chordal(nx.complete_graph(3)) assert nx.is_chordal(nx.cycle_graph(3)) assert not nx.is_chordal(nx.cycle_graph(5)) with pytest.raises(nx.NetworkXError, match="Input graph is not chordal"): nx.is_chordal(self.self_loop_G)
def test_triangulate(): # Generate random graphs from nodes count nodes = [2, 10, 25, 50, 75, 100] graphs = [nx.gnp_random_graph(n, 0.5, directed=False) for n in nodes] wi_graphs = [mb.Graph.from_networkx(G) for G in graphs] wi_triang = [mb.triangulate(graph) for graph in wi_graphs] wi_triang = [nx.is_chordal(graph.to_networkx()) for graph in wi_triang] assert (all(wi_triang))
def score(self, graph, entropy_map): graph = graph.copy() if not nx.is_chordal(graph): graph = utils.tools.triangulate(graph) clique_list = [ tuple(sorted(clique)) for clique in nx.find_cliques(graph) ] clique_graph = nx.Graph() clique_graph.add_nodes_from(clique_list) for clique1, clique2 in itertools.combinations(clique_list, 2): clique_graph.add_edge(clique1, clique2, weight=-len(set(clique1) & set(clique2))) junction_tree = nx.minimum_spanning_tree(clique_graph) # print(' clique list', len(clique_list), clique_list) # junction tree size size = 0 for clique in clique_list: temp_size = self.domain.project(clique).size() # if temp_size > self.config['max_clique_size'] or len(clique) > 15: if temp_size > self.config['max_clique_size']: return self.min_score, 0, size size += temp_size if size > self.config['max_parameter_size']: return self.min_score, 0, size # KL divergence # model entropy is for debugging and can not be used for constructing model as they are not dp KL_divergence = 0 model_entropy = 0 entropy, noisy_entropy = utils.tools.dp_entropy( entropy_map, self.data, self.domain, clique_list[0], self.entropy_noise) KL_divergence += noisy_entropy model_entropy += entropy for start, clique in nx.dfs_edges(junction_tree, source=clique_list[0]): # print(clique, self.data.shape) entropy, noisy_entropy = utils.tools.dp_entropy( entropy_map, self.data, self.domain, clique, self.entropy_noise) KL_divergence += noisy_entropy model_entropy += entropy separator = set(start) & set(clique) if len(separator) != 0: entropy, noisy_entropy = utils.tools.dp_entropy( entropy_map, self.data, self.domain, separator, self.entropy_noise) KL_divergence -= noisy_entropy model_entropy -= entropy # print('KL', KL_divergence, size) score = -KL_divergence - self.config['size_penalty'] * size return score, model_entropy, size
def markov_add_or_remove(g, num_steps): all_edges = set(combinations(g.nodes, 2)) for _ in range(num_steps): flag = random.randint(0, 1) if flag == 0: u, v = random.sample(g.edges, 1)[0] g.remove_edge(u, v) while not nx.is_connected(g) or not nx.is_chordal(g): g.add_edge(u, v) u, v = random.sample(g.edges, 1)[0] g.remove_edge(u, v) else: u, v = random.sample(all_edges - g.edges, 1)[0] g.add_edge(u, v) while not nx.is_connected(g) or not nx.is_chordal(g): g.remove_edge(u, v) u, v = random.sample(all_edges - g.edges, 1)[0] g.add_edge(u, v)
def test_complete_to_chordal_graph(self): fgrg = nx.fast_gnp_random_graph test_graphs = [ nx.barbell_graph(6, 2), nx.cycle_graph(15), nx.wheel_graph(20), nx.grid_graph([10, 4]), nx.ladder_graph(15), nx.star_graph(5), nx.bull_graph(), fgrg(20, 0.3, seed=1), ] for G in test_graphs: H, a = nx.complete_to_chordal_graph(G) assert nx.is_chordal(H) assert len(a) == H.number_of_nodes() if nx.is_chordal(G): assert G.number_of_edges() == H.number_of_edges() assert set(a.values()) == {0} else: assert len(set(a.values())) == H.number_of_nodes()
def run(self): self.alpha = {} for C in self.component_subgraphs: # get triangulation for each connected component of the reduced graph G_c: self.edges_of_triangulation += self.triangulate(C) self.H = self.G.copy() self.H.add_edges_from(self.edges_of_triangulation) if not nx.is_chordal(self.H): raise ta.TriangulationNotSuccessfulException( "Resulting graph is somehow not chordal!")
def test_is_chordal(self): assert not nx.is_chordal(self.non_chordal_G) assert nx.is_chordal(self.chordal_G) assert nx.is_chordal(self.connected_chordal_G) assert nx.is_chordal(nx.complete_graph(3)) assert nx.is_chordal(nx.cycle_graph(3)) assert not nx.is_chordal(nx.cycle_graph(5))
def test_is_chordal(self): assert_false(nx.is_chordal(self.non_chordal_G)) assert_true(nx.is_chordal(self.chordal_G)) assert_true(nx.is_chordal(self.connected_chordal_G)) assert_true(nx.is_chordal(nx.complete_graph(3))) assert_true(nx.is_chordal(nx.cycle_graph(3))) assert_false(nx.is_chordal(nx.cycle_graph(5)))
def test_bayesian_model(self): self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"), ("d", "a")]) phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6)) phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12)) phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20)) phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) bm = self.graph.to_bayesian_model() self.assertIsInstance(bm, BayesianModel) self.assertListEqual(sorted(bm.nodes()), ["a", "b", "c", "d"]) self.assertTrue(nx.is_chordal(bm.to_undirected()))
def test_bayesian_model(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) bm = self.graph.to_bayesian_model() self.assertIsInstance(bm, BayesianModel) self.assertListEqual(sorted(bm.nodes()), ['a', 'b', 'c', 'd']) self.assertTrue(nx.is_chordal(bm.to_undirected()))
def compute_chromatic(masses, window): G = nx.Graph() for i in range(0, len(masses)): G.add_node(i) for i in range(0, len(masses)): for j in range(i + 1, len(masses)): if abs(masses[j] - masses[i]) <= window*2.0: G.add_edge(i, j) else: break assert(nx.is_chordal(G)) setlist = nx.chordal_graph_cliques(G) return max([len(x) for x in setlist])
def Chordal(P, tipo, ruta): RUTA = ruta + '/NetWX/files/' path = Path(RUTA) path.mkdir(parents=True, exist_ok=True) P_is_chordal = [] for i in range(len(P)): P_is_chordal.append(is_chordal(P[i])) P_is_chordal = DataFrame(is_chordal) P_is_chordal.to_csv(RUTA + tipo + " - is chordal.txt", sep='\t', header=None, index=False)
def tree_insertion(num_nodes, num_edges, return_tree=False): tree = nx.random_tree(num_nodes) chordal = Graph(tree) while len(chordal.edges) < num_edges: u, v = random.sample(chordal.nodes, 2) chordal.add_edge(u, v) while not nx.is_chordal(chordal): chordal.remove_edge(u, v) u, v = random.sample(chordal.nodes, 2) chordal.add_edge(u, v) if not return_tree: return chordal return tree, chordal
def test_bayesian_model(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = DiscreteFactor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = DiscreteFactor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = DiscreteFactor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = DiscreteFactor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) bm = self.graph.to_bayesian_model() self.assertIsInstance(bm, BayesianModel) self.assertListEqual(sorted(bm.nodes()), ['a', 'b', 'c', 'd']) self.assertTrue(nx.is_chordal(bm.to_undirected()))
def get_clique_tree(nodes: Iterable[int], edges: List[Tuple[int, int]]) -> nx.Graph: """ Given a set of int nodes i and edges (i,j), returns a clique tree. Clique tree is an object G for which: - G.nodes[i]['members'] contains the set of original nodes in the ith maximal clique - G[i][j]['members'] contains the set of original nodes in the seperator set between maximal cliques i and j Note: This method is currently only implemented for chordal graphs; TODO: add a step to triangulate non-chordal graphs. Parameters ---------- nodes A list of nodes indices edges A list of tuples, where each tuple has indices for connected nodes Returns ------- networkx.Graph An object G representing clique tree """ # Form the original graph G1 G1 = nx.Graph() G1.add_nodes_from(nodes) G1.add_edges_from(edges) # Check if graph is chordal # TODO: Add step to triangulate graph if not if not nx.is_chordal(G1): raise NotImplementedError("Graph triangulation not implemented.") # Create maximal clique graph G2 # Each node is a maximal clique C_i # Let w = |C_i \cap C_j|; C_i, C_j have an edge with weight w if w > 0 G2 = nx.Graph() for i, c in enumerate(nx.chordal_graph_cliques(G1)): G2.add_node(i, members=c) for i in G2.nodes: for j in G2.nodes: S = G2.nodes[i]["members"].intersection(G2.nodes[j]["members"]) w = len(S) if w > 0: G2.add_edge(i, j, weight=w, members=S) # Return a minimum spanning tree of G2 return nx.minimum_spanning_tree(G2)
def is_triangulated(self): """ Checks whether the undirected graph is triangulated or not. Examples -------- >>> from pgmpy.base import UndirectedGraph >>> G = UndirectedGraph() >>> G.add_edges_from([('x1', 'x2'), ('x1', 'x3'), ('x1', 'x4'), ... ('x2', 'x4'), ('x3', 'x4')]) >>> G.is_triangulated() True """ return nx.is_chordal(self)
def markov_add_remove(g, num_steps): # The input should be a UCCG. all_edges = set(combinations(g.nodes, 2)) for _ in range(num_steps): u, v = random.sample(g.edges, 1)[0] a, b = random.sample(all_edges - g.edges, 1)[0] g.remove_edge(u, v) g.add_edge(a, b) while not nx.is_connected(g) or not nx.is_chordal(g): g.add_edge(u, v) g.remove_edge(a, b) u, v = random.sample(g.edges, 1)[0] a, b = random.sample(all_edges - g.edges, 1)[0] g.remove_edge(u, v) g.add_edge(a, b)
def print_is_of_type_attrs(graph): print("\n====== is of type X? ======") print("Directed? ->", "Yes" if nx.is_directed(graph) else "No") print("Directed acyclic? ->", "Yes" if nx.is_directed_acyclic_graph(graph) else "No") print("Weighted? ->", "Yes" if nx.is_weighted(graph) else "No") if nx.is_directed(graph): print("Aperiodic? ->", "Yes" if nx.is_aperiodic(graph) else "No") print("Arborescence? ->", "Yes" if nx.is_arborescence(graph) else "No") print("Weakly Connected? ->", "Yes" if nx.is_weakly_connected(graph) else "No") print("Semi Connected? ->", "Yes" if nx.is_semiconnected(graph) else "No") print("Strongly Connected? ->", "Yes" if nx.is_strongly_connected(graph) else "No") else: print("Connected? ->", "Yes" if nx.is_connected(graph) else "No") print("Bi-connected? ->", "Yes" if nx.is_biconnected(graph) else "No") if not graph.is_multigraph(): print("Chordal? -> ", "Yes" if nx.is_chordal(graph) else "No") print("Forest? -> ", "Yes" if nx.is_chordal(graph) else "No") print("Distance regular? -> ", "Yes" if nx.is_distance_regular(graph) else "No") print("Eulerian? -> ", "Yes" if nx.is_eulerian(graph) else "No") print("Strongly regular? -> ", "Yes" if nx.is_strongly_regular(graph) else "No") print("Tree? -> ", "Yes" if nx.is_tree(graph) else "No")
def test_hypertree(self): """ Méthode qui va retourner True ou False si le graphe est ou n'est pas un hypetree. Pour ça, elle va vérifier la chordalité et les cliques du graphe """ primal = self.getPrimal() isClique = self.checkClique() #O(m²n²) isChodal = nx.is_chordal(primal) #O(m*n) if isChodal and isClique: plt.show() return True else: plt.show() return False
def is_triangulated(self): """ Checks whether the undirected graph is triangulated (also known as chordal) or not. Chordal Graph: A chordal graph is one in which all cycles of four or more vertices have a chord. Examples -------- >>> from pgmpy.base import UndirectedGraph >>> G = UndirectedGraph() >>> G.add_edges_from(ebunch=[('x1', 'x2'), ('x1', 'x3'), ... ('x2', 'x4'), ('x3', 'x4')]) >>> G.is_triangulated() False >>> G.add_edge(u='x1', v='x4') >>> G.is_triangulated() True """ return nx.is_chordal(self)
def is_chordal(g, **kwargs): return nx.is_chordal(g)
import networkx as nx f = open("stats_chord.txt",'r') lignes = f.readlines() f.close() for ligne in lignes: ligne = ligne.split(',') for i in ligne : i = i.replace("\n", "") G = nx.parse_edgelist(ligne, nodetype = int) print nx.is_chordal(G)