Example #1
0
    def add_new_state_node(self, t):
        if len(self.variables["states"]) > t:
            # the state already exists in the graph.
            return
        else:
            if t == 0:
                P = self.get_prior_factor()
                self.factors["transition"].append(pm.DiscreteDistribution(P)) # add prior factor
                self.variables["states"].append(pm.State( self.factors["transition"][t], name="Damage {}".format(t)))
                self.add_node(self.variables["states"][t])
            else:
                T = self.get_transition_factor()
                # check if we have a controlA
                if len(self.variables["controlAs"]) > t-1:
                    self.factors["transition"].append(pm.ConditionalProbabilityTable(T, [self.factors["transition"][t-1],self.factors["controlA"][t-1]]))
                else:
                    self.factors["transition"].append(pm.ConditionalProbabilityTable(T, [self.factors["transition"][t-1],self.factors["controlP"][t-1]]))

                # add RV as a node in the graph
                self.variables["states"].append(pm.State( self.factors["transition"][t], name="Damage {}".format(t)))
                self.add_node(self.variables["states"][t])

                # connect node via transition edge
                self.add_edge(self.variables["states"][t-1], self.variables["states"][t] )

                # connect node via control edge
                if len(self.variables["controlAs"]) > t-1:
                    self.add_edge(self.variables["controlAs"][t-1], self.variables["states"][t] )
                else:
                    self.add_edge(self.variables["controlPs"][t-1], self.variables["states"][t] )
Example #2
0
    def __set_target_probability(self):

        for i in range(action.Action.num_actions):
            if i != action.Action.ST:
                prob_value = 0.5
                if self.__target_vec != None:
                    direction_vec = action.VECTOR[i]
                    direction_vec.normalize()
                    self.__target_vec.normalize()
                    dot = self.__target_vec.dot_product(direction_vec)
                    self.__target_dots[i] = dot
                    prob_value = self.__target_threshold + (
                        1.0 - self.__target_threshold) * max(0, dot)
                self.__d_target[i] = pm.ConditionalProbabilityTable(
                    [['T', 'T', prob_value], ['T', 'F', 1.0 - prob_value],
                     ['F', 'T', 0.5], ['F', 'F', 0.5]],
                    [self.__d_direction[i]])
            else:
                self.__target_dots[i] = 0
                self.__d_target[i] = pm.ConditionalProbabilityTable(
                    [['T', 'T', 0.5], ['T', 'F', 0.5], ['F', 'T', 0.5],
                     ['F', 'F', 0.5]], [self.__d_direction[i]])

        self.__s_target = [
            pm.State(self.__d_target[i], name='target_' + str(i))
            for i in range(action.Action.num_actions)
        ]
Example #3
0
	def fit(self, similarBldDF):
		'''
		climate zone, Design cooling load and principle building activity are parents attributes of main cooling equipment.
		Census division, main cooling equipment, cooling degree days, percentage of building cooled are four parent attribute of high efficient building
		Attributes:
			similarBldDF, a pandas DataFrame object includes a group of building similar to the proposed 
				building.This object is used to train the Bayesian Network classifier.

		'''
		climateZoneDict,COOLLOADDict,principleActivityNDict,MAINCLCPTList,MAINCLDict,CDD65NDict,HECSCPTList=self.attributeDistribution(similarBldDF)

		climateZone=pm.DiscreteDistribution(climateZoneDict)
		designCoolingLoad=pm.DiscreteDistribution(COOLLOADDict)
		principleBuildingActivity=pm.DiscreteDistribution(principleActivityNDict)
		coolingDegreeDays = pm.DiscreteDistribution(CDD65NDict)

		#MCE_CPT is the conditional probability table of main cooling equipment
		mainCoolingEquipmentCPT=pm.ConditionalProbabilityTable(MAINCLCPTList,[climateZone,designCoolingLoad,principleBuildingActivity])
		#HECS_CPT is the conditional probability table of high efficient cooling system.
		highEfficientCoolingSystemCPT=pm.ConditionalProbabilityTable(HECSCPTList,[mainCoolingEquipmentCPT,principleBuildingActivity,\
	                                                                           coolingDegreeDays])
		
		#the first layer parent attributes
		p1_climateZone=pm.Node(climateZone,name="climateZone")#climateZone
		p1_COOLLOAD=pm.Node(designCoolingLoad,name="COOLLOAD")#COOLLOAD
		p1_principleActivity=pm.Node(principleBuildingActivity,name="principleActivity")#principleActivity

		#the second layer parent attributes
		#the main cooling equipment
		p2_MAINCL = pm.Node(mainCoolingEquipmentCPT,name="MAINCL")#
		p2_CDD65 = pm.Node(coolingDegreeDays,name="CDD65")

		#high efficient cooling system
		p_HECS = pm.Node(highEfficientCoolingSystemCPT, name="highEfficientCoolingSystemCPT")

		#the Bayesian Network for the main cooling equipment
		modelMCE = pm.BayesianNetwork("Main cooling equipment")
		modelMCE.add_nodes(p1_climateZone,p1_COOLLOAD,p1_principleActivity,p2_MAINCL,p2_CDD65,p_HECS)
		modelMCE.add_edge(p1_climateZone,p2_MAINCL)
		modelMCE.add_edge(p1_COOLLOAD,p2_MAINCL)
		modelMCE.add_edge(p1_principleActivity,p2_MAINCL)
		modelMCE.add_edge(p2_MAINCL,p_HECS)
		modelMCE.add_edge(p1_principleActivity,p_HECS)
		modelMCE.add_edge(p2_CDD65,p_HECS)
		modelMCE.bake()
		self.BN4CLfitted=modelMCE
Example #4
0
 def add_new_obs_node(self, t, sensor_measurement):
     O = self.get_observation_factor(sensor_measurement)
     self.factors["observation"].append(pm.ConditionalProbabilityTable(O, [self.factors["transition"][t]]))
     self.variables["observations"].append(pm.State( self.factors["observation"][t], name="Observation {}".format(t)))
     self.evidence["Observation {}".format(t)] = json.dumps(sensor_measurement)
     # add RV as a node in the graph
     self.add_node(self.variables["observations"][t])
     # connect node via observation edge
     self.add_edge(self.variables["states"][t], self.variables["observations"][t] )
Example #5
0
    def add_new_ref_obs_node(self, t):
        if len(self.variables["ref_observations"]) > t:
            #node is already in the graph
            return
        else:
            self.factors["ref_observation"].append(pm.ConditionalProbabilityTable(self.Q_factor, [self.factors["transition"][t]]))
            self.variables["ref_observations"].append(pm.State(self.factors["ref_observation"][t], name="Ref. Observation {}".format(t)))

            # add RV as a node in the graph
            self.add_node(self.variables["ref_observations"][t])
            # connect node via ref observation edge
            self.add_edge(self.variables["states"][t], self.variables["ref_observations"][t] )
Example #6
0
    def add_new_controlP_node(self,t):
        # 'Predicted' or estimated control node
        if len(self.variables["controlPs"]) > t:
            #node is already in the graph
            return
        else:
            C = self.get_controlP_factor()
            self.factors["controlP"].append(pm.ConditionalProbabilityTable(C, [self.factors["transition"][t]]))
            self.variables["controlPs"].append(pm.State(self.factors["controlP"][t], name="ControlP {}".format(t)))

            # add RV as a node in the graph
            self.add_node(self.variables["controlPs"][t])
            # connect node via observation edge
            self.add_edge(self.variables["states"][t], self.variables["controlPs"][t] )
Example #7
0
def probDiagnose(percList):
    """
    Funzione che riceve in input una lista con tre tuple contenenti ognuna una
    categoria e la loro percentuale e, attraverso l'uso di una rete bayesiana ed
    il calcolo delle probabilità condizionate, restituisce una lista con le 
    probabilità delle categorie delle diagnosi condizionate dalle categorie
    dei sintomi
    
    Parameters
    ----------
    percList: list
        Lista contenente tre tuple: ogni tupla contiene una categoria  e la
        rispettiva percentuale(per i sintomi) 
    
    Returns
    -------
    condProbList: list
        Lista contenente tre tuple: ogni tupla contiene una categoria e la
        rispettiva probabilità(per le diagnosi)  
    """
    import pomegranate as pg
    sym = pg.DiscreteDistribution({
        'gen': 192. / 389,
        'sup': 125. / 389,
        'inf': 72. / 389
    })
    diagn = pg.ConditionalProbabilityTable(
        [['gen', 'gen', 0.5], ['gen', 'sup', 0.25], ['gen', 'inf', 0.25],
         ['sup', 'gen', 0.20], ['sup', 'sup', 0.75], ['sup', 'inf', 0.05],
         ['inf', 'gen', 0.2], ['inf', 'sup', 0.05], ['inf', 'inf', 0.75]],
        [sym])

    s1 = pg.State(sym, name="sym")
    s2 = pg.State(diagn, name="diagn")

    model = pg.BayesianNetwork("Diagnose finder")
    model.add_states(s1, s2)
    model.add_edge(s1, s2)
    model.bake()

    condProbList = []
    for i in percList:
        beliefs1 = model.predict_proba({'sym': i[1]})
        condProbList.append(beliefs1[1].parameters[0])

    return condProbList
Example #8
0
def _solve_bayes_network(cpts, conditionals=None):
    print(f'cpts: {cpts}')
    print(f'conditionals: {cpts}')
    model = pmg.BayesianNetwork("User Produced Model")
    states = []
    distributions = []
    cond = []
    _cond_stage = []

    def _translator(string):
        if string == 0 or string == '0':
            return 'True'
        elif string == 1 or string == '1':
            return 'False'
        else:
            return None

    counter = 0
    for i, name in enumerate(cpts.keys()):
        temp_dict = cpts[name].to_dict()
        if name not in conditionals:
            for k in temp_dict.keys():
                distributions.append(pmg.DiscreteDistribution(temp_dict[k]))
                states.append(pmg.State(distributions[counter], name=name))
                counter += 1
        else:
            _cond_stage.append(i)
            for col in temp_dict.keys():
                for val in temp_dict[col].keys():
                    arr = [_translator(col), val, temp_dict[col][val]]
                    cond.append(arr)

            print(f'cond: {cond}')
            states.append(
                pmg.State(pmg.ConditionalProbabilityTable(cond, distributions),
                          name=name))
    for i, s in enumerate(states):
        print(f'i: {i}')
        print(f's: {s}')
        model.add_states(s)
        if i not in _cond_stage and _cond_stage:
            model.add_edge(s, states[_cond_stage[0]])
    model.bake()
    return model
    def _calculate_one(self) -> np.ndarray:
        """Run the calculation
        """

        # Get the sequence of states
        dist_1 = pm.DiscreteDistribution(
            {"wet": 0.5, "dry": 0.5}
        )  # random starting point
        dist_2 = pm.ConditionalProbabilityTable(
            [
                ["wet", "wet", self.param["pi_1"]],
                ["wet", "dry", 1 - self.param["pi_1"]],
                ["dry", "wet", 1 - self.param["pi_2"]],
                ["dry", "dry", self.param["pi_2"]],
            ],
            [dist_1],
        )
        markov_chain = pm.MarkovChain([dist_1, dist_2])
        years = self._get_time("all")
        states = markov_chain.sample(years.size)

        # Get the conditional expected value
        mu_1_vec = self.param["mu_1"] + self.param["gamma_1"] * years
        mu_2_vec = self.param["mu_2"] + self.param["gamma_2"] * years
        mu_vec = mu_1_vec
        mu_vec[np.where(np.array(states) == "wet")] = mu_2_vec[
            np.where(np.array(states) == "wet")
        ]

        # get conditional variance
        sigma_vec = self.param["coeff_var"] * mu_vec
        sigma_vec[sigma_vec < self.param["sigma_min"]] = self.param["sigma_min"]

        # get and the streamflow
        sflow = np.exp(np.random.normal(loc=mu_vec, scale=sigma_vec))
        return sflow
Example #10
0
def export_pom(net, by='index'):
    '''
    Returns
    -------
    pomegranate BN Model based on given DAG.
    Assume my "sort" function correctly returns a list where
    children are allways ranked higher than parents. If Pommegranate is used
    to estimate model likelihood, all outcomes must be of the same data type. 
    Either All int or all string. 
    '''
    s = topoSort(net.export_nds())
    model = pm.BayesianNetwork("DIY_GRN")

    # Convert Top Level nodes to Discrete distributions
    top = [i for i in s if len(i.par) == 0]
    topStates = {}

    for n in top:
        pr = n.cpt['Prob'].to_dict()
        if by == 'index':
            va = n.cpt[n.idx].to_dict()
        else:
            va = n.cpt[n.label].to_dict()
        dist = {}
        for v in va.keys():
            dist[va[v]] = pr[v]

        dist = pm.DiscreteDistribution(dist)
        if by == 'index':
            state = pm.Node(dist, name=str(n.idx))
            topStates[str(n.idx)] = state
        else:
            state = pm.Node(dist, name=str(n.label))
            topStates[str(n.label)] = state

        model.add_state(state)

    # Convert Depent Nodes to Conditional Distributions
    dep = [i for i in s if len(i.par) != 0]
    depStates = {}

    for n in dep:

        # Convert floats cpt outcome levels to integers if needed
        if isinstance(n.cpt.iloc[0, 0], np.int64):
            cpt = [fl(l) for l in n.cpt.values.tolist()]

        else:
            cpt = n.cpt.values.tolist()

        # Vector of ID for each parent
        if by == 'index':
            par_id = [str(i.idx) for i in n.par]
        else:
            par_id = [str(i.label) for i in n.par]

        # Validate that all parents have been processed
        for p in par_id:
            if (not p in topStates.keys()) and (not p in depStates.keys()):
                print("Problem with parent:", p, "of node:", n.idx)
                return [topStates, depStates]

        par = [
            topStates[i] if i in topStates.keys() else depStates[i]
            for i in par_id if i in topStates.keys() or i in depStates.keys()
        ]

        cpt = pm.ConditionalProbabilityTable(cpt,
                                             [p.distribution for p in par])

        if by == 'index':
            state = pm.Node(cpt, name=str(n.idx))
            depStates[str(n.idx)] = state

        else:
            state = pm.Node(cpt, name=str(n.label))
            depStates[str(n.label)] = state

        # Add node to model
        model.add_state(state)

        # Add edges from parent to this node
        for p in par:
            model.add_edge(p, state)

    # Assemble and "Bake" model
    model.bake()
    return (model)
Example #11
0
import matplotlib.image
import itertools as it
import pomegranate as pom
import pygraphviz
import tempfile

F = 'Fraud'
T = 'Travel'
OD = 'OwnsDevice'
FP = 'ForeignPurchase'
OP = 'OnlinePurchase'

travelDist = pom.DiscreteDistribution({False: 0.05, True: 0.95})

foreignPurchaseDist = pom.ConditionalProbabilityTable(
    [[False, False, 0.9999], [False, True, 0.0001], [True, False, 0.12],
     [True, True, 0.88]], [travelDist])

ownsDeviceDist = pom.DiscreteDistribution({False: 0.3, True: 0.7})

onlinePurchaseDist = pom.ConditionalProbabilityTable(
    [[False, False, 0.9995], [False, True, 0.0005], [True, False, 0.60],
     [True, True, 0.40]], [ownsDeviceDist])

fraudDist = pom.ConditionalProbabilityTable(
    [[False, False, False, 0.25], [False, True, False, 0.15],
     [True, False, False, 0.20], [True, True, False, 0.0005],
     [False, False, True, 0.75], [False, True, True, 0.85],
     [True, False, True, 0.80], [True, True, True, 0.9995]],
    [onlinePurchaseDist, travelDist])
Example #12
0
    def __init__(self, map_manager, agent_type, sampling=False):
        self.__map_manager = map_manager
        self.__position = None
        self.__percept = None
        self.__action_map = None
        self.__target_threshold = 0.3
        self.__max_prob_dir = None

        # target dot products
        self.__target_dots = [None] * action.Action.num_actions

        # Random variables marked as true will be considered in the bayesian net
        self._considered = {
            'target': True,
            'danger': True,
            'obstruction': True,
            'visibility': True,
            'hider': True,
            'seeker': True,
            'blockage': True
        }

        if agent_type == agent.AgentType.Seeker:
            self._considered['danger'] = False

        self.__sampling = sampling

        # Probability distributions

        self.__d_direction = [
            pm.DiscreteDistribution({
                'T': 0.5,
                'F': 0.5
            }) for i in range(action.Action.num_actions)
        ]
        self.__s_direction = [
            pm.State(self.__d_direction[i], name='direction_' + str(i))
            for i in range(action.Action.num_actions)
        ]

        # Random vars, probability distributions and state vars of considered variables
        # in the bayesian net
        if self._considered['target']:
            self.__r_target = [None] * action.Action.num_actions
            self.__d_target = [None] * action.Action.num_actions
            self.__s_target = None

        if self._considered['danger']:
            self.__r_danger = [None] * action.Action.num_actions
            self.__d_danger = [
                pm.ConditionalProbabilityTable(
                    [['T', '0', 0.99], ['T', '1', 0.01], ['F', '0', 0.5],
                     ['F', '1', 0.5]], [self.__d_direction[i]])
                for i in range(action.Action.num_actions)
            ]
            self.__s_danger = [
                pm.State(self.__d_danger[i], name='danger_' + str(i))
                for i in range(action.Action.num_actions)
            ]

        if self._considered['obstruction']:
            self.__r_obstruction = [None] * action.Action.num_actions
            self.__d_obstruction = [
                pm.ConditionalProbabilityTable(
                    [['T', '0', 0.001], ['T', '1', 0.003], ['T', '2', 0.006],
                     ['T', '3', 0.99], ['F', '0', 1. / 4], ['F', '1', 1. / 4],
                     ['F', '2', 1. / 4], ['F', '3', 1. / 4]],
                    [self.__d_direction[i]])
                for i in range(action.Action.num_actions)
            ]
            self.__s_obstruction = [
                pm.State(self.__d_obstruction[i], name='obstruction_' + str(i))
                for i in range(action.Action.num_actions)
            ]

        if self._considered['visibility']:
            self.__r_visibility = [None] * action.Action.num_actions
            self.__d_visibility = [
                pm.ConditionalProbabilityTable(
                    [['T', '0', 0.001], ['T', '1', 0.003], ['T', '2', 0.006],
                     ['T', '3', 0.99], ['F', '0', 1. / 4], ['F', '1', 1. / 4],
                     ['F', '2', 1. / 4], ['F', '3', 1. / 4]],
                    [self.__d_direction[i]])
                for i in range(action.Action.num_actions)
            ]
            self.__s_visibility = [
                pm.State(self.__d_visibility[i], name='visibility_' + str(i))
                for i in range(action.Action.num_actions)
            ]

        cpt_a = [['T', '0', 0.9], ['T', '1', 0.066], ['T', '2', 0.033],
                 ['F', '0', 1. / 3], ['F', '1', 1. / 3], ['F', '2', 1. / 3]]

        cpt_b = [['T', '0', 0.9], ['T', '1', 0.077], ['T', '2', 0.022],
                 ['F', '0', 1. / 3], ['F', '1', 1. / 3], ['F', '2', 1. / 3]]

        target_cpt = None

        if self._considered['hider']:
            if agent_type == agent.AgentType.Hider:
                target_cpt = cpt_a
            elif agent_type == agent.AgentType.Seeker:
                target_cpt = cpt_b
            self.__r_hider = [None] * action.Action.num_actions
            self.__d_hider = [
                pm.ConditionalProbabilityTable(target_cpt,
                                               [self.__d_direction[i]])
                for i in range(action.Action.num_actions)
            ]
            self.__s_hider = [
                pm.State(self.__d_hider[i], name='hider_' + str(i))
                for i in range(action.Action.num_actions)
            ]

        if self._considered['seeker']:
            if agent_type == agent.AgentType.Hider:
                target_cpt = cpt_b
            elif agent_type == agent.AgentType.Seeker:
                target_cpt = cpt_a
            self.__r_seeker = [None] * action.Action.num_actions
            self.__d_seeker = [
                pm.ConditionalProbabilityTable(target_cpt,
                                               [self.__d_direction[i]])
                for i in range(action.Action.num_actions)
            ]
            self.__s_seeker = [
                pm.State(self.__d_seeker[i], name='seeker_' + str(i))
                for i in range(action.Action.num_actions)
            ]

        if self._considered['blockage']:
            self.__r_blockage = [None] * action.Action.num_actions
            self.__d_blockage = [
                pm.ConditionalProbabilityTable(
                    [['T', '0', 0.999999], ['T', '1', 0.000001],
                     ['F', '0', 0.5], ['F', '1', 0.5]],
                    [self.__d_direction[i]])
                for i in range(action.Action.num_actions)
            ]
            self.__s_blockage = [
                pm.State(self.__d_blockage[i], name='blockage_' + str(i))
                for i in range(action.Action.num_actions)
            ]

        # State objects(for pomegranate) library which hold both the distribution as well as name
        self.__model = None
        self.__inferred_results = None
        self.__direction_probs = [None] * action.Action.num_actions
        self.__direction_dist = None
Example #13
0
 def get_conditional_probability_table(self, conditional_probability_table):
     tbl = self._rows.get_table()
     cpts = self._parents.get_parents_table(conditional_probability_table)
     if cpts is None: return None
     out = pg.ConditionalProbabilityTable(tbl, cpts)
     return out
Example #14
0
# A -> B -> C
n = 6
t = s - 3
distA = pm.DiscreteDistribution({
    "F": max_cdf[n - 1, t],
    "S": 1 - max_cdf[n - 1, t]
})

cpd = [
    ["F", "F", max_cdf[n - 1, t]],
    ["F", "S", 1 - max_cdf[n - 1, t]],
    ["S", "F", max_cdf[n, t]],
    ["S", "S", 1 - max_cdf[n, t]],
]

distB_A = pm.ConditionalProbabilityTable(cpd, [distA])
distC_B = pm.ConditionalProbabilityTable(cpd, [distB_A])
# distD_C = pm.ConditionalProbabilityTable(cpd, [distC_B])

A = pm.Node(distA, name="A")
B = pm.Node(distB_A, name="B")
C = pm.Node(distC_B, name="C")
# D = pm.Node(distD_C, name="D")

model = pm.BayesianNetwork("Chain Model")
model.add_states(A, B, C)  #, D)
model.add_edge(A, B)
model.add_edge(B, C)
# model.add_edge(C, D)
model.bake()
t = 4

ppd_A = {
    "S": sf[n, t - 2],
    "F": 1 - sf[n, t - 2],
}
dist_A = pm.DiscreteDistribution(ppd_A)

cpd_B_A = [
    ["S", "S", sf[n + 1, t - 1]],
    ["S", "F", 1 - sf[n + 1, t - 1]],
    ["F", "S", sf[n, t - 1]],
    ["F", "F", 1 - sf[n, t - 1]],
]

dist_B_A = pm.ConditionalProbabilityTable(cpd_B_A, [dist_A])

cpd_C_B = [
    ["S", "S", sf[n + 1, t]],
    ["S", "F", 1 - sf[n + 1, t]],
    ["F", "S", sf[n, t]],
    ["F", "F", 1 - sf[n, t]],
]

dist_C_B = pm.ConditionalProbabilityTable(cpd_C_B, [dist_B_A])

A = pm.Node(dist_A, name="A")
B = pm.Node(dist_B_A, name="B")
C = pm.Node(dist_C_B, name="C")

model = pm.BayesianNetwork("Chain Model")
Example #16
0
    def export_pom(self):
        '''
        Returns
        -------
        pomegranate BN Model based on given DAG.
        Assume my "sort" function correctly returns a list where
        children are allways ranked higher than parents
        '''
        s = self.sort_nodes(l=list(self.nds.values()))
        model = pm.BayesianNetwork("DIY_GRN")

        # Convert Top Level nodes to Discrete distributions
        top = [i for i in s if len(i.par) == 0]
        topStates = {}

        for n in top:
            pr = n.cpt['Prob'].to_dict()
            va = n.cpt[n.idx].to_dict()
            dist = {}
            for v in va.keys():
                dist[va[v]] = pr[v]

            dist = pm.DiscreteDistribution(dist)
            state = pm.Node(dist, name="G" + str(n.idx))

            topStates["G" + str(n.idx)] = state
            model.add_state(state)

        # Convert Depent Nodes to Conditional Distributions
        dep = [i for i in s if len(i.par) != 0]
        depStates = {}

        for n in dep:

            # Convert floats cpt outcome levels to integers if needed
            if isinstance(n.cpt.iloc[0, 0], np.int64):
                cpt = [fl(l) for l in n.cpt.values.tolist()]

            else:
                cpt = n.cpt.values.tolist()

            # Vector of ID for each parent
            par_id = ["G" + str(i.idx) for i in n.par]

            # Validate that all parents have been processed
            for p in par_id:
                if (not p in topStates.keys()) and (not p in depStates.keys()):
                    print("Problem with parent:", p, "of node:", n.idx)
                    return [topStates, depStates]

            # Get all parents found in the topStates dict
            par = [topStates[i] for i in par_id if i in topStates.keys()]

            # Add all parents in the depStates dict
            par = par + [depStates[i] for i in par_id if i in depStates.keys()]

            cpt = pm.ConditionalProbabilityTable(cpt,
                                                 [p.distribution for p in par])

            state = pm.Node(cpt, name="G" + str(n.idx))
            depStates["G" + str(n.idx)] = state

            # Add node to model
            model.add_state(state)

            # Add edges from parent to this node
            for p in par:
                model.add_edge(p, state)

        # Assemble and "Bake" model
        model.bake()
        return (topStates, depStates, model)
    def create_graph(self, name_network="Byesian netowrk"):
        """
        Metodo per create il modello di rete bayesiana (tramite pomegranate) a partire dai dati caricati dal file XML.

        :param name_network: nome della rete bayesiana
        :type name_network: stringa

        :return: Modello pomegranate della rete bayesiana
        :rtype: pomegranate.BayesianNetwork
        """

        cpt_node = {}
        pg_node = {}
        model = pomegranate.BayesianNetwork(name_network)

        for node_name in self.nodes_list:
            if not self.parents[node_name]:
                dict_dist = {}
                for elem in self.name_classes_nodes[node_name]:
                    dict_dist[elem] = self.cpt_nodes[node_name][0][self.name_classes_nodes[node_name].index(elem)]
                # print("name_prior: {}".format(node_name))
                self.nodes[node_name] = pomegranate.DiscreteDistribution(dict_dist)
                # print(self.nodes[node_name])
                pg_node[node_name] = pomegranate.Node(self.nodes[node_name], name=node_name)
            else:
                cpt_pg = []
                parent_list = self.parents[node_name].copy()
                parent_list.reverse()

                mod_list = [len(self.name_classes_nodes[node_name])]

                for i in range(len(parent_list) - 1):
                    mul = mod_list[i] * len(self.name_classes_nodes[parent_list[i]])
                    mod_list.append(mul)

                cont = 0
                for elem in self.cpt_nodes[node_name]:
                    for prob in elem:
                        row = [prob, self.name_classes_nodes[node_name][cont % mod_list[0]]]

                        for parent in parent_list:
                            attr = (cont // mod_list[parent_list.index(parent)]) % len(self.name_classes_nodes[parent])
                            row.append(self.name_classes_nodes[parent][attr])
                        cont += 1
                        row.reverse()
                        cpt_pg.append(row)
                cpt_node[node_name] = cpt_pg

        for node_name in self.nodes_list:
            if self.parents[node_name]:
                # print("parents: {}".format(self.parents[node_name]))
                parent_node_list = []
                for parent in self.parents[node_name]:
                    parent_node_list.append(self.nodes[parent])
                self.nodes[node_name] = pomegranate.ConditionalProbabilityTable(cpt_node[node_name], parent_node_list)
                # print("node {}: {}".format(node_name,self.nodes[node_name]))
                # print("parent_node_list: {}".format(parent_node_list))
                pg_node[node_name] = pomegranate.Node(self.nodes[node_name], name=node_name)

        for node_name in self.nodes_list:
            # le distribuzioni di output seguono l'ordine con cui vengono aggiunti i nodi qui
            model.add_node(pg_node[node_name])

        for node_name in self.nodes_list:
            # print("name {}".format(node_name))
            for parent in self.parents[node_name]:
                # print("parent {}".format(parent))
                model.add_edge(pg_node[parent], pg_node[node_name])

        model.bake()

        return model