package bayesGame.bayesbayes.nodeCPD; import java.util.ArrayList; import java.util.Arrays; import org.apache.commons.math3.fraction.Fraction; import bayesGame.bayesbayes.BayesNode; public class MajorityVote implements NodeCPD { public MajorityVote() { // TODO Auto-generated constructor stub } @Override public BayesNode getNode(BayesNode sourceBayesNode, Object[] parents) { Object nodeType = sourceBayesNode.type; ArrayList<Object> allItems = new ArrayList<Object>(Arrays.asList(parents)); allItems.add(0, parents); // generate a truth table as per http://stackoverflow.com/a/10761325/2130838 int rows = (int) Math.pow(2, allItems.size()); for (int i=0; i<rows; i++) { int balance=0; boolean trueSeen = false; ArrayList<Object> falseObjects = new ArrayList<Object>(); for (int j=allItems.size()-1; j>=0; j--) { // as we traverse each generated row from the end of the row, we keep track of // for the balance of TRUE-FALSE items. // Also, for each FALSE item on the row, we add that to the list of false items // on this row. if (j > 0){ if((i/(int) Math.pow(2, j))%2 == 1){ balance++; } else { balance--; falseObjects.add(allItems.get(j)); } } else { Fraction probability; // once we get to the beginning of the row, we check whether // this row codes for the node being TRUE or FALSE if((i/(int) Math.pow(2, j))%2 == 1){ // if this row codes for the node being TRUE and the // balance is positive, then we set the probability of // this row to one. if the balance is negative we set // the probability of this row to zero, and if the balance // is even we set the probability to .5. if (balance > 0){ probability = Fraction.ONE; } else if (balance < 0){ probability = Fraction.ZERO; } else{ probability = Fraction.ONE_HALF; } } else { // Similarly, if this row codes for the node being FALSE, // we do the reverse. falseObjects.add(nodeType); if (balance > 0){ probability = Fraction.ZERO; } else if (balance < 0){ probability = Fraction.ONE; } else{ probability = Fraction.ONE_HALF; } } sourceBayesNode.setProbabilityOfUntrueVariables(probability, falseObjects.toArray()); } } } String description = "<html>'" + sourceBayesNode.type + "' is a <b>conditional probability variable</b><br>of type <b>majority vote</b>.<p><p>It is true if the majority of its parents are true, <br>and false if the majority of its parents are false. <br>If an equal number of parents are true and false, <br>it has a 50% chance of being true."; sourceBayesNode.cptDescription = description; return sourceBayesNode; } }