def minimal_imap(self, order):
        """
        Returns a Bayesian Model which is minimal IMap of the Joint Probability Distribution
        considering the order of the variables.

        Parameters
        ----------
        order: array-like
            The order of the random variables.

        Examples
        --------
        >>> from pgmpy.factors import JointProbabilityDistribution
        >>> prob = JointProbabilityDistribution(['x1', 'x2', 'x3'], [2, 3, 2], np.ones(12)/12)
        >>> bayesian_model = prob.minimal_imap(order=['x2', 'x1', 'x3'])
        >>> bayesian_model
        <pgmpy.models.models.models at 0x7fd7440a9320>
        """
        from pgmpy import models as bm
        import itertools

        def combinations(u):
            for r in range(len(u) + 1):
                for i in itertools.combinations(u, r):
                    yield i

        G = bm.BayesianModel()
        for variable_index in range(len(order)):
            u = order[:variable_index]
            for subset in combinations(u):
                if self.check_independence(order[variable_index],
                                           set(u) - set(subset), subset):
                    G.add_edges_from([(variable, order[variable_index])
                                      for variable in subset])
        return G
Esempio n. 2
0
    def red_bayesiana(self):
        """
        Creamos la red bayesiana con la librería pgmpy
    	"""
        Buscaminas_bayesiano = pgmm.BayesianModel()
        """
        Variables importantes:
         x_totales: casillas ocultas totales del tablero
         x_ocultas: casillas ocultas con vecinos destapados
         y_destapadas: casillas destapadas
    	"""
        x_ocultas = []
        x_totales = []
        y_destapadas = []
        casilla_oculta_sin_colindantes_destapados = False
        """
        Añadimos los nodos a la red.
        Serán las casillas ocultas con vecinos destapados y las casillas destapadas.
    	"""
        for fila in range(self.filas):
            for columna in range(self.columnas):
                # Si la casilla no está pulsada
                if (self.tableroOculto[fila][columna] == 'T'):
                    x = 'Tapada{0}{1}'.format(
                        fila,
                        columna)  # Lo pone en formato Tapada01,Tapada02...

                    x_totales.append(
                        x
                    )  # Añadimos las casillas sin pulsar a la variable x_totales

                    casilla_tiene_vecinos_destapados = False
                    # Obtenemos la posicion de las casillas vecinas
                    casillas_vecinas = me.posicion_casillas_vecinas(
                        self.tableroOculto, fila, columna)

                    # Recorro todas las casillas vecinas de la casilla en la que estamos actualmente
                    for vecino in casillas_vecinas:
                        # Comprobamos que los vecinos de la casilla estan destapados
                        if (self.tableroOculto[int(vecino[0])][int(vecino[1])]
                                != 'T'):
                            casilla_tiene_vecinos_destapados = True
                            break

                    # Comprobamos que la casilla actual tiene vecino destapado
                    if (casilla_tiene_vecinos_destapados
                            or not casilla_oculta_sin_colindantes_destapados):
                        # Si lo tiene, añadimos la casilla a la lista de casillas tapadas con vecinos destapados
                        x_ocultas.append(x)
                        Buscaminas_bayesiano.add_nodes_from([
                            x
                        ])  # Se añade la casilla como nodo de nuestra red

                    if (not casilla_tiene_vecinos_destapados):
                        casilla_oculta_sin_colindantes_destapados = True

                # Si la casilla está pulsada
                else:
                    y = 'Destapada{0}{1}'.format(
                        fila, columna
                    )  # lo pone en formato Destapada 01,Destapada 02...

                    #Listado_de_minas = listado_de_minas(tableroBuscaminas) # Variable que contiene la posición de las minas del tablero
                    casilla_tiene_vecinos_ocultos = False
                    casillas_vecinas = me.posicion_casillas_vecinas(
                        self.tableroOculto, fila, columna)

                    for vecino in casillas_vecinas:
                        casilla_vecina_oculta = 'Tapada{0}{1}'.format(
                            vecino[0], vecino[1])
                        if (self.tableroOculto[int(vecino[0])][int(
                                vecino[1])] == 'T'
                                and not self.Minas_encontradas.__contains__(
                                    casilla_vecina_oculta)):
                            casilla_tiene_vecinos_ocultos = True
                            break

                    if (casilla_tiene_vecinos_ocultos):
                        y_destapadas.append(y)
                        Buscaminas_bayesiano.add_nodes_from([y])

        print("Lista de casillas vecinas ocultas:\n")
        print(x_ocultas)
        print("Lista de casillas destapadas:\n")
        print(y_destapadas)

        print("Lista de minas encontradas:\n")
        print(self.Minas_encontradas)
        """
        Añadimos las aristas entre los nodos.
        Las casillas destapadas tendrán aristas con sus vecinas ocultas
    	"""
        Aristas = dict()
        for fila in range(self.filas):
            for columna in range(self.columnas):
                y = 'Destapada{0}{1}'.format(fila, columna)

                # Si la casilla ha sido destapada y se ha añadido a la lista de casillas destapadas
                if (self.tableroOculto[fila][columna] != 'T'
                        and y_destapadas.__contains__(y)):
                    ListaColindantesOcultos = []

                    # Obtenemos la posicion de las casillas vecinas
                    casillas_vecinas = me.posicion_casillas_vecinas(
                        self.tableroOculto, fila, columna)

                    # Recorremos sus vecinos
                    for vecino in casillas_vecinas:
                        x = 'Tapada{0}{1}'.format(vecino[0], vecino[1])

                        # Si el vecino es oculto añadimos la arista de la destapada a la tapada
                        if (x_ocultas.__contains__(x)):
                            Buscaminas_bayesiano.add_edges_from([(x, y)])
                            ListaColindantesOcultos.append(x)

                    # Asociamos la casilla destapada con todos sus vecinos ocultos
                    Aristas.update({y: ListaColindantesOcultos})
        """
	        Generación de tablas de probabilidad (CPDs)
	         Las tablas de probabilidad de las casillas tapadas no dependen de nada.
	         Las tablas de probabilidad de las casillas destapadas dependen de sus casillas vecinas tapadas.	
		    Para cada variable creamos una instancia de la clase `TabularCPD`, proporcionando:
		    Nombre de la variable (atributo `variable`),
		    Cantidad de valores (cardinalidad) que puede tomar (atributo `variable_card`),
		    Lista de listas, conteniendo cada una de estas las probabilidades para un valor concreto, 
		    según los valores de los padres (atributo `values`, el valor se transforma a un array),
		    Lista con los nombres de los padres (atributo `evidence`, valor `None` si no se proporciona),
		    Lista con la cantidad de valores (cardinalidad) que puede tomar cada uno de los padres (atributo `evidence_card`, 
		    valor `None` si no se proporciona).
    	"""
        """
        	Tabla de probabilidad de las casillas tapadas
   		"""

        ListadoDestapadas = dict()
        for fila in range(self.filas):
            for columna in range(self.columnas):

                x = 'Tapada{0}{1}'.format(fila, columna)
                y = 'Destapada{0}{1}'.format(fila, columna)
                if (self.tableroOculto[fila][columna] == 'T'
                        and x_ocultas.__contains__(x)):

                    # Si la casilla por detapar es una mina
                    if (self.Minas_encontradas.__contains__(x)):
                        probabilidad_mina = 1

                    # Si el numero de casillas por destapar es mayor que el numero de minas que tiene el tablero
                    elif (len(x_ocultas) > 0):
                        probabilidad_mina = (self.minas - len(
                            self.Minas_encontradas)) / len(x_totales)

                    else:
                        probabilidad_mina = 0

                    # Añadimos la cpd al modelo
                    cpd = pgmf.TabularCPD(
                        x, 2, [[1 - probabilidad_mina, probabilidad_mina]])
                    Buscaminas_bayesiano.add_cpds(cpd)

                # CPD de Destapadas
                elif (self.tableroOculto[fila][columna] != 'T'
                      and y_destapadas.__contains__(y)):

                    ListadoDestapadas.update(
                        {y: int(self.tableroOculto[fila][columna])})

                    #A continuación divido entre los valores que puede tener 'Destapada' en función de las minas que tenga alrededor
                    nColumnasCPD = pow(2, len(Aristas[y]))

                    numero_maximo_minas = 9

                    if (fila == 0 or fila == self.filas - 1):
                        numero_maximo_minas = 6
                    if (columna == 0 or columna == self.columnas - 1):

                        if (numero_maximo_minas == 6):
                            numero_maximo_minas = 4

                        else:
                            numero_maximo_minas = 6

                    if (len(Aristas[y]) + 1 < numero_maximo_minas):
                        numero_maximo_minas = len(Aristas[y]) + 1

                    listaProb = []
                    for var in range(numero_maximo_minas):
                        listaFila = []
                        contador = 0
                        for x in range(nColumnasCPD):
                            if (var == bin(contador).count('1')):
                                listaFila.append(1)
                            else:
                                listaFila.append(0)
                            contador += 1

                        listaProb.append(listaFila)

                    ListaCardinalidad = []
                    for _ in range(len(Aristas[y])):
                        ListaCardinalidad.append(2)

                    cpd = pgmf.TabularCPD(y, numero_maximo_minas, listaProb,
                                          Aristas[y], ListaCardinalidad)
                    Buscaminas_bayesiano.add_cpds(cpd)

        Buscaminas_bayesiano_ev = pgmi.VariableElimination(
            Buscaminas_bayesiano)

        consultas = []
        for var in x_ocultas:
            if (not var in self.Minas_encontradas):
                consulta = Buscaminas_bayesiano_ev.query([var],
                                                         ListadoDestapadas)
                consultas.append(consulta)

        ocultasProbabilidadDeNoSerMina = dict()
        for var in consultas:
            x = ''
            probabilidadDeNoSerMina = 0
            for var1 in var.keys():
                x = str(var1)
            for var2 in var.values():
                probabilidadDeNoSerMina = float(var2.values[0])

            if (probabilidadDeNoSerMina == 0.0):
                self.Minas_encontradas.append(x)

            ocultasProbabilidadDeNoSerMina.update({x: probabilidadDeNoSerMina})

        maximaProbabilidadDeNoSerMina = 0.
        ocultaMaximaProbabilidadDeNoSerMina = ''
        mejor_oculta = []
        print("Oculta con mayor probabilidad de no ser mina")
        for x, probabilidadDeNoSerMina in ocultasProbabilidadDeNoSerMina.items(
        ):
            print("x: {0} -> Probabilidad de no ser mina: {1}".format(
                x, probabilidadDeNoSerMina))
            if (maximaProbabilidadDeNoSerMina < probabilidadDeNoSerMina):
                ocultaMaximaProbabilidadDeNoSerMina = str(x)
                maximaProbabilidadDeNoSerMina = probabilidadDeNoSerMina
                mejor_oculta = []
                mejor_oculta.append(ocultaMaximaProbabilidadDeNoSerMina)

            if (probabilidadDeNoSerMina == 1.0 and not x in mejor_oculta):
                mejor_oculta.append(x)

        self.mejor_oculta = mejor_oculta
        print(
            "Lista de mejores ocultas con alta probabilidad de no ser minas: {0}"
            .format(self.mejor_oculta))
Esempio n. 3
0
def gameNetworkGenerator(game):
    #Definimos el tablero
    graph = []
    width = game.board.board_width
    height = game.board.board_height
    #Averiguamos los vecinos de cada Y y creamos un conjunto con todos los nodos y las aristas relacionadas.
    for i in range(width):
        for j in range(height):
            vecinos = game.neightbours_of_position(i, j)
            for x in range(0, len(vecinos)):
                graph.append((vecinos[x], "Y" + str(i) + str(j)))

    #Añadimos a la modelo bayesiano la información obtenida anteriormente
    Modelo_msgame = pgmm.BayesianModel(graph)

    probabilidadBomba = game.board.num_mines / ((game.board.board_height) *
                                                (game.board_width))
    probabilidadNoBomba = 1 - probabilidadBomba
    modelnodes = Modelo_msgame.nodes()
    modelnodesY = Modelo_msgame.nodes()

    res = [s for s in modelnodes if 'X' in s]

    #"A partir de aqui se obtienen las CPDS de las Xij"
    for e in range(0, len(res)):
        cpd_msgameX = "cpd_msgame" + (res[e])
        cpd_msgameX = pgmf.TabularCPD(
            res[e], 2, [[probabilidadNoBomba, probabilidadBomba]])
        Modelo_msgame.add_cpds(cpd_msgameX)

    resY = [s for s in modelnodesY if 'Y' in s]
    for l in range(0, len(resY)):
        i = resY[l][1:2]
        j = resY[l][2:3]
        vecinos = game.neightbours_of_position(int(i), int(j))
        listOpt = [0, 1]
        #Se realizan las combinaciones
        resA = list(product(listOpt, repeat=len(vecinos)))

        #Se suman los unos de cada una de las combinaciones, es decir, se suman el número de bombas
        def counterPermutations(lsa):
            count = 0
            for f in range(len(lsa)):
                if lsa[f] is 1:
                    count = count + 1
            return count

        #Generamos tantas listas como Y necesitamos + 1 (incluyendo la inexistencia de bomba)
        probabilidades_unidas = []
        for v in range(len(vecinos) + 1):
            probabilidades_calculadas = []
            for a in range(len(resA)):
                lsta = resA[a]
                counter = counterPermutations(lsta)
                if counter is v:
                    probabilidades_calculadas.append(1)
                else:
                    probabilidades_calculadas.append(0)
            probabilidades_unidas.append(probabilidades_calculadas)
        #Generamos la CPD
        cpd_letrasY = "cpd_letras" + (resY[l])
        cpd_letrasY = pgmf.TabularCPD(resY[l],
                                      len(vecinos) + 1, probabilidades_unidas,
                                      vecinos, [2] * len(vecinos))
        Modelo_msgame.add_cpds(cpd_letrasY)

    return Modelo_msgame
Esempio n. 4
0
def generate_DAG(height, width):            
    n = height
    m = width
    modelo_buscaminas = pgmm.BayesianModel()
    
    for i in range(1,n+1):
        for j in range(1,m+1):
            if i==1:
                if j==1:
                    # El vértice Y11 siempre tiene los mismos
                    # vecinos: X21, X22 y X12
                    modelo_buscaminas.add_edges_from([('X21', 'Y11'),
                                                      ('X22', 'Y11'),
                                                      ('X12', 'Y11')])
                elif j==m:
                    # El vértice Y1,m posee siempre los mismos
                    # vecinos: X1,m-1 y X2,m y X2,m-1:
                    modelo_buscaminas.add_edges_from([('X1'+str(m-1), 'Y1'+str(m)),
                                                      ('X2'+str(m), 'Y1'+str(m)),
                                                      ('X2'+str(m-1), 'Y1'+str(m))])
                else:
                    # Se añaden las aristas correspondientes a
                    # los vértices Y1,j donde se cumple que 1<j<m
                    modelo_buscaminas.add_edges_from([('X'+str(i)+str(j-1), 'Y1'+str(j)),
                                                      ('X'+str(i)+str(j+1), 'Y1'+str(j)),
                                                      ('X'+str(i+1)+str(j-1), 'Y1'+str(j)),
                                                      ('X'+str(i+1)+str(j), 'Y1'+str(j)),
                                                      ('X'+str(i+1)+str(j+1), 'Y1'+str(j))])
            elif i==n:
                if j==1:
                    # El vértice Yn,1 posee 3 vecinos que son:
                    # Xn,2, Xn-1,1 y Xn-1,2:
                    modelo_buscaminas.add_edges_from([('X'+str(n)+str(2), 'Y'+str(n)+str(1)),
                                                      ('X'+str(n-1)+str(1), 'Y'+str(n)+str(1)),
                                                      ('X'+str(n-1)+str(2), 'Y'+str(n)+str(1))])
                elif j==m:
                    # El vértice Yn,m posee como vecinos los
                    # siguientes vértices: Xn,m-1, Xn-1,m y Xn-1,m-1
                    modelo_buscaminas.add_edges_from([('X'+str(n)+str(m-1), 'Y'+str(n)+str(m)),
                                                      ('X'+str(n-1)+str(m), 'Y'+str(n)+str(m)),
                                                      ('X'+str(n-1)+str(m-1), 'Y'+str(n)+str(m))])
                else:
                    # Los vecinos de los vértices Yn,j en los que
                    # 1<j<m son: Xn,j-1, Xn,j+1, Xn-1,j-1, Xn-1,j y Xn-1,j+1
                    modelo_buscaminas.add_edges_from([('X'+str(n)+str(j-1), 'Y'+str(n)+str(j)),
                                                      ('X'+str(n)+str(j+1), 'Y'+str(n)+str(j)),
                                                      ('X'+str(n-1)+str(j-1), 'Y'+str(n)+str(j)),
                                                      ('X'+str(n-1)+str(j), 'Y'+str(n)+str(j)),
                                                      ('X'+str(n-1)+str(j+1), 'Y'+str(n)+str(j))])  
            else:
                # En esta rama, añadiremos las aristas de
                # aquellos vértices Yi,j siendo 1<i<m. 
                if j==1:
                    # Subrama 1: se añaden las aristas para los
                    # vértices Yi,1 y sus correspondientes vecinos
                    modelo_buscaminas.add_edges_from([('X'+str(i)+str(2), 'Y'+str(i)+str(1)),
                                                      ('X'+str(i+1)+str(1), 'Y'+str(i)+str(1)),
                                                      ('X'+str(i+1)+str(2), 'Y'+str(i)+str(1)),
                                                      ('X'+str(i-1)+str(1), 'Y'+str(i)+str(1)),
                                                      ('X'+str(i-1)+str(2), 'Y'+str(i)+str(1))])
                elif j==m:
                    # Subrama 2: se añaden las aristas para los
                    # vértices Yi,m y sus correspondientes vecinos
                    modelo_buscaminas.add_edges_from([('X'+str(i)+str(m-1), 'Y'+str(i)+str(m)),
                                                      ('X'+str(i+1)+str(m), 'Y'+str(i)+str(m)),
                                                      ('X'+str(i+1)+str(m-1), 'Y'+str(i)+str(m)),
                                                      ('X'+str(i-1)+str(m), 'Y'+str(i)+str(m)),
                                                      ('X'+str(i-1)+str(m-1), 'Y'+str(i)+str(m))])
                else:
                    # Subrama 3: se añaden las aristas para los
                    # vértices Yi,j donde 1<j<m y sus correspondientes vecinos
                    modelo_buscaminas.add_edges_from([('X'+str(i)+str(j+1), 'Y'+str(i)+str(j)),
                                                      ('X'+str(i)+str(j-1), 'Y'+str(i)+str(j)),
                                                      ('X'+str(i+1)+str(j-1), 'Y'+str(i)+str(j)),
                                                      ('X'+str(i+1)+str(j), 'Y'+str(i)+str(j)),
                                                      ('X'+str(i+1)+str(j+1), 'Y'+str(i)+str(j)),
                                                      ('X'+str(i-1)+str(j-1), 'Y'+str(i)+str(j)),
                                                      ('X'+str(i-1)+str(j), 'Y'+str(i)+str(j)),
                                                      ('X'+str(i-1)+str(j+1), 'Y'+str(i)+str(j))])         
    
    return modelo_buscaminas
Esempio n. 5
0
print("\n--------------------------------------------------------\n")
print("Aristas:\n")
'''
    Guardamos las aristas
'''
for edge in XML.get_edges():
    edges.append(edge)

print(edges)

print("\n========================================================\n")
print("Impresion del Modelo Bayesiano\n")
'''
    Creamos el modelo
'''
Modelo = pgmn.BayesianModel()
Modelo.add_nodes_from(variables)
Modelo.add_edges_from(edges)

print("Variables o nodos:")
print(Modelo.nodes())
print("\n")
print("Aristas:")
print(Modelo.edges())
print("\n")
'''
    Metemos los tabular_cpds al modelo, que luego nos serviran para sacar las tablas de propiedades
'''
for variable, valores in XML.variable_CPD.items():
    cpd = pgmf.TabularCPD(
        variable,