package edu.neu.ccs.evergreen.model; import edu.neu.ccs.evergreen.util.AppMean; import edu.neu.ccs.evergreen.util.AppSAT; import edu.neu.ccs.evergreen.util.Polynomial; /** * Tracks the weight of the system. * */ public class Weights { private int weights[] = new int[256]; private int total; private Polynomial polynomial; /** * @see java.lang.Object#clone() */ public Weights clone() { Weights newWeights = new Weights(); System.arraycopy(weights, 0, newWeights.weights, 0, weights.length); newWeights.total = total; newWeights.polynomial = polynomial; return newWeights; } /** * Add the given weight to the relation number. * * @param relationNumber * Relation number * @param weight * Weight */ public void addWeight(int relationNumber, int weight) { weights[relationNumber] += weight; total += weight; if (polynomial != null) { polynomial = polynomial.add(AppSAT.appSAT(relationNumber).multiply( weight)); } } /** * Subtract the given weight from the relation number. * * @param relationNumber * Relation number * @param weight * Weight */ public void subtractWeight(int relationNumber, int weight) { weights[relationNumber] -= weight; total -= weight; if (polynomial != null) { polynomial = polynomial.subtract(AppSAT.appSAT(relationNumber) .multiply(weight)); } } /** * Change the weight from the old relation number to the new relation * number. * * @param oldRelationNumber * Old relation number * @param newRelationNumber * New relation number * @param weight * Weight */ public void switchWeight(int oldRelationNumber, int newRelationNumber, int weight) { subtractWeight(oldRelationNumber, weight); addWeight(newRelationNumber, weight); } /** * Get the total weight. * * @return Total weight */ public int getTotal() { return total; } /** * Internal method to get the polynomial used for calculations. * * @return Polynomial */ public Polynomial getPolynomial() { if (polynomial == null) { createPolynomial(); } return polynomial.multiply(1.0 / (double) total); } /** * Solve the polynomial given by this weight. * * @return Y value at maximum X */ public double solve() { Polynomial temp = getPolynomial(); return temp.eval(AppMean.maxX0To1(temp)); } /** * Determine max bias based on the weights. * * @return Maximum X */ public double maxBias() { return AppMean.maxX0To1(getPolynomial()); } /** * Create the initial polynomial. */ private void createPolynomial() { polynomial = null; for (int relationNumber = 0; relationNumber < weights.length; relationNumber++) { if (weights[relationNumber] > 0) { Polynomial temp = AppSAT.appSAT(relationNumber); temp = temp.multiply(weights[relationNumber]); if (polynomial == null) { polynomial = temp; } else { polynomial = polynomial.add(temp); } } } } /** * @see java.lang.Object#toString() */ @Override public String toString() { StringBuffer result = new StringBuffer(); for (int relationNumber = 0; relationNumber < weights.length; relationNumber++) { if (weights[relationNumber] > 0) { if (result.length() > 0) { result.append(", "); } result.append(relationNumber); result.append("="); result.append(weights[relationNumber]); } } return result.toString(); } /** * Calculate the number of clauses satisfied for the given bias. * * @param bias * Bias * @return Percentage of clauses satisfied */ public double satisfiedPercentage(double bias) { return getPolynomial().eval(bias); } }