001    package aima.probability;
002    
003    import java.util.Hashtable;
004    import java.util.Iterator;
005    import java.util.List;
006    
007    import aima.util.Util;
008    
009    /**
010     * @author Ravi Mohan
011     * 
012     */
013    
014    public class EnumerationAsk {
015    
016            public static double[] ask(Query q, BayesNet net) {
017                    String queryVariable = q.getQueryVariable();
018                    Hashtable<String, Boolean> evidenceVariables = q.getEvidenceVariables();
019    
020                    double[] probDist = new double[2];
021                    // true probability
022                    evidenceVariables.put(q.getQueryVariable(), new Boolean(true));
023                    probDist[0] = enumerateAll(net, net.getVariables(), evidenceVariables);
024                    // false probability
025                    evidenceVariables.put(q.getQueryVariable(), new Boolean(false));
026                    probDist[1] = enumerateAll(net, net.getVariables(), evidenceVariables);
027                    // System.out.println( probDist[0] + " " + probDist[1]);
028                    // return probDist;
029                    double[] normalized = Util.normalize(probDist);
030                    // System.out.println( normalized[0] + " " + normalized[1]);
031                    return normalized;
032            }
033    
034            private static double enumerateAll(BayesNet net, List unprocessedVariables,
035                            Hashtable<String, Boolean> evidenceVariables) {
036                    if (unprocessedVariables.size() == 0) {
037    
038                            return 1.0;
039                    } else {
040                            String Y = (String) unprocessedVariables.get(0);
041    
042                            if (evidenceVariables.keySet().contains(Y)) {
043    
044                                    double probYGivenParents = net.probabilityOf(Y,
045                                                    evidenceVariables.get(Y), evidenceVariables);
046    
047                                    double secondTerm = enumerateAll(net, Util
048                                                    .rest(unprocessedVariables), evidenceVariables);
049    
050                                    return probYGivenParents * secondTerm;
051                            } else {
052                                    double sigma = 0.0;
053                                    Hashtable<String, Boolean> clone1 = cloneEvidenceVariables(evidenceVariables);
054                                    clone1.put(Y, Boolean.TRUE);
055                                    double probYTrueGivenParents = net.probabilityOf(Y,
056                                                    Boolean.TRUE, clone1);
057    
058                                    double secondTerm = enumerateAll(net, Util
059                                                    .rest(unprocessedVariables), clone1);
060    
061                                    double trueProbabilityY = probYTrueGivenParents * secondTerm;
062    
063                                    Hashtable<String, Boolean> clone2 = cloneEvidenceVariables(evidenceVariables);
064                                    clone2.put(Y, Boolean.FALSE);
065                                    double probYFalseGivenParents = net.probabilityOf(Y,
066                                                    Boolean.FALSE, clone2);
067    
068                                    secondTerm = enumerateAll(net, Util.rest(unprocessedVariables),
069                                                    clone2);
070                                    double falseProbabilityY = probYFalseGivenParents * secondTerm;
071                                    // System.out.print(secondTerm + " ) )");
072                                    sigma = trueProbabilityY + falseProbabilityY;
073                                    return sigma;
074    
075                            }
076                    }
077    
078            }
079    
080            private static Hashtable<String, Boolean> cloneEvidenceVariables(
081                            Hashtable<String, Boolean> evidence) {
082                    Hashtable<String, Boolean> cloned = new Hashtable<String, Boolean>();
083                    Iterator<String> iter = evidence.keySet().iterator();
084                    while (iter.hasNext()) {
085                            String key = iter.next();
086                            Boolean bool = evidence.get(key);
087                            if (bool.equals(Boolean.TRUE)) {
088                                    cloned.put(key, Boolean.TRUE);
089                            } else if ((evidence.get(key)).equals(Boolean.FALSE)) {
090                                    cloned.put(key, Boolean.FALSE);
091                            }
092                    }
093                    return cloned;
094            }
095    
096    }