Ejemplo n.º 1
0
        /// <summary>
        /// Paso de mensajes hacia abajo de la red para hacer backtraking de las probabilidades
        /// </summary>
        /// <param name="Y">Vertice</param>
        /// <param name="X">Vertice</param>
        private void SendLambdaMessage(Vertex Y, Vertex X)
        {
            double        denomitator  = 0;
            List <string> lstNormalize = new List <string>();

            //Para cada valor de X
            foreach (var xVal in X.Val)
            {
                //Sumatora para cada valor de Y
                double sumYVals = 0;
                foreach (var yVal in Y.Val)
                {
                    //Para todos los valores de las probabilidades posibles de los padres de Y diferentes a X
                    double        sum       = 0;
                    List <Vertex> lstParent = Y.Parents.Where(parent => parent.Name != X.Name).ToList();
                    foreach (var permutation in Vertex.GetValuePermutations(lstParent))
                    {
                        string s            = yVal.Name + "|" + xVal.Name + ",";
                        double productioria = 1;
                        for (int i = 0; i < permutation.Count; i++)
                        {
                            var val = permutation[i];
                            productioria *= _messages.PiMessage[Y.Name][val.Name];
                            s            += i == permutation.Count - 1 ? val.Name : val.Name + ",";
                        }
                        sum += P[s] * productioria;
                    }
                    sumYVals += sum * yVal.LambdaValue;
                }
                SetLambdaMessage(Y.Name, xVal.Name, sumYVals);

                //Para cada hijo U de X multiplicar los mensajes lambd de U con el valor xVal
                double productoria = 1;
                foreach (var U in X.Childs)
                {
                    productoria *= _messages.LambdaMessage[U.Name][xVal.Name];
                }
                xVal.LambdaValue = productoria;

                //P(x|{a})
                string name = xVal.Name + "|" + Get_a();
                P[name] = xVal.LambdaValue * xVal.PiValue * Alpha;

                //Valores para la normalizacion
                denomitator += P[name];
                lstNormalize.Add(name);
            }

            //Normalizar P(x|a)
            foreach (var e in lstNormalize)
            {
                P[e] = P[e] / denomitator;
            }

            //Para cada padre Z de X que no esta en A
            foreach (var Z in X.Parents)
            {
                if (!A.Contains(Z))
                {
                    SendLambdaMessage(X, Z);
                }
            }

            //for cada W hijo de X que sea diferente de Y
            foreach (var W in X.Childs)
            {
                if (Y.Name != W.Name)
                {
                    SendPiMessage(X, W);
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Paso de mensajes hacia arriba de la red para hacer backtraking de las probabilidades
        /// </summary>
        /// <param name="Z">Vertice</param>
        /// <param name="X">Vertice</param>
        private void SendPiMessage(Vertex Z, Vertex X)
        {
            //Calculate pix for valor val in Z
            foreach (var zVal in Z.Val)
            {
                //Se optiene el pi message de x con el valor val con los valores de los hijos de Z
                double multi = 1;
                foreach (var child in Z.Childs)
                {
                    if (X != child)
                    {
                        multi *= _messages.LambdaMessage[child.Name][zVal.Name];
                    }
                }
                double newValue = zVal.PiValue * multi;
                SetPiMessages(X.Name, zVal.Name, newValue);
            }

            //Si no contiene A
            if (!A.Contains(X))
            {
                double        denomitator  = 0;
                List <string> lstNormalize = new List <string>();

                //Para cada valor de X
                foreach (var xVal in X.Val)
                {
                    //Para todos los valores de las probabilidades posibles de los padres de X
                    double sum = 0;
                    foreach (var permutation in Vertex.GetValuePermutations(X.Parents))
                    {
                        string s            = xVal.Name + "|";
                        double productioria = 1;
                        for (int i = 0; i < permutation.Count; i++)
                        {
                            var val = permutation[i];
                            productioria *= _messages.PiMessage[X.Name][val.Name];
                            s            += i == permutation.Count - 1 ? val.Name : val.Name + ",";
                        }
                        sum += P[s] * productioria;
                    }
                    xVal.PiValue = sum;

                    string name = xVal.Name + "|" + Get_a();
                    P[name] = xVal.LambdaValue * xVal.PiValue * Alpha;

                    //Valores para la normalizacion
                    denomitator += P[name];
                    lstNormalize.Add(name);
                }

                //Normalizar P(x|a)
                foreach (var e in lstNormalize)
                {
                    P[e] = P[e] / denomitator;
                }

                //for cada Y en los hijos de X
                foreach (var Y in X.Childs)
                {
                    SendPiMessage(X, Y);
                }
            }

            //Si no todos los valores lambda de x son igual a 1
            bool condition = false;

            foreach (var xVal in X.Val)
            {
                if (xVal.LambdaValue >= 1)
                {
                    condition = true;
                }
            }

            //Enviar mensajes a todos los W que son padres de X y no son Z ni estan A
            if (condition)
            {
                foreach (var W in X.Parents)
                {
                    if (W.Name != Z.Name && A.Contains(W) == false)
                    {
                        SendLambdaMessage(X, W);
                    }
                }
            }
        }