package dkohl.bayes.inference; import java.util.LinkedList; import java.util.List; import dkohl.bayes.bayesnet.BayesNet; import dkohl.bayes.probability.Assignment; import dkohl.bayes.probability.ProbabilityAssignment; import dkohl.bayes.probability.Variable; /** * Enumeration Algorithm: Exact inference in Baysian Networks. * * @author Daniel Kohlsdorf * */ public class EnumerateAll { /** * The probability distribution of a variable. * * @param query * the variable * @param net * the bayes net defining the independence * @param assignments * a set of assignments in this net. * @return */ public static List enumerateAsk( Variable query, BayesNet net, List assignments) { LinkedList variables = net.getVariables(); LinkedList result = new LinkedList(); // Evaluate probability for each possible // value of the variable by enumeration for (String value : query.getDomain()) { LinkedList temp = new LinkedList(); temp.addAll(assignments); temp.add(new Assignment(query, value)); double prob = enumerateAll(net, variables, temp); result.add(new ProbabilityAssignment(query, value, prob)); } return result; } /** * Decides if a variable is hidden or not. A variable is hidden if it is not * assigned. * * @param variable * the variable in question. * @param assignments * all the assignments * @return true if not assigned */ private static boolean hidden(Variable variable, LinkedList assignments) { for (Assignment assignment : assignments) { if (assignment.getVariable().getName().equals(variable.getName())) { return false; } } return true; } /** * Recursively evaluate probability of an assignment. * * Can be seen as depth first search + backtracking (branching on hidden * nodes) * * @param net * a bayes net defining independence * @param variables * the variables left to evaluate * @param assignments * all assignments * @return */ public static double enumerateAll(BayesNet net, List variables, LinkedList assignments) { // if no variables left to evaluate, // leaf node reached. if (variables.isEmpty()) { return 1; } // evaluate variable, recurse on rest // PROLOG: [Variable|Rest]. Variable variable = variables.get(0); List rest = variables.subList(1, variables.size()); // if current variable is hidden if (hidden(variable, assignments)) { // sum out all possible values for that variable double sumOut = 0; for (String value : variable.getDomain()) { // by temporarily adding each value to the asigned variable set LinkedList temp = new LinkedList(); temp.addAll(assignments); temp.add(new Assignment(variable, value)); // then evaluate this variable double val = net.getNodes().get(variable.getName()).eval(temp) .getProbability(); // and all that depend on it val *= enumerateAll(net, rest, temp); sumOut += val; } return sumOut; } // if not just evaluate variable and continue. return net.getNodes().get(variable.getName()).eval(assignments) .getProbability() * enumerateAll(net, rest, assignments); } }