예제 #1
0
	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
		
예제 #2
0
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)
예제 #3
0
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)
예제 #4
0
파일: graph.py 프로젝트: ncullen93/pyBN
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)
예제 #5
0
 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 "========================"
예제 #6
0
    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
예제 #7
0
    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"
예제 #10
0
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
예제 #11
0
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
예제 #12
0
    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
예제 #13
0
    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))
예제 #15
0
 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)
예제 #16
0
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))
예제 #17
0
    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
예제 #18
0
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)
예제 #19
0
 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()
예제 #20
0
    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!")
예제 #21
0
 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))
예제 #22
0
 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)))
예제 #23
0
 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)))
예제 #24
0
    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()))
예제 #25
0
    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()))
예제 #26
0
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])
예제 #27
0
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)
예제 #28
0
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()))
예제 #30
0
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)
예제 #31
0
    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)
예제 #32
0
    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)
예제 #33
0
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)
예제 #34
0
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")
예제 #35
0
    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)
예제 #38
0
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)