/// <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); } } }
public static void AddEdge(ref Vertex padre, ref Vertex hijo) { hijo.Parents.Add(padre); padre.Childs.Add(hijo); }
/// <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); } } } }