edu.uci.imbs.actor.VariablePopulationProtectionStatistics.java Source code

Java tutorial

Introduction

Here is the source code for edu.uci.imbs.actor.VariablePopulationProtectionStatistics.java

Source

/* Copyright (c) 2013, Regents of the University of California.  See License.txt for details */

package edu.uci.imbs.actor;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeSet;

import org.apache.commons.math3.stat.descriptive.moment.Mean;
import org.apache.commons.math3.stat.descriptive.rank.Median;
import org.apache.log4j.Logger;

public class VariablePopulationProtectionStatistics extends ProtectionStatistics {
    private static Logger logger = Logger.getLogger(VariablePopulationProtectionStatistics.class);
    private Map<Double, Integer> distribution;
    private HashMap<Double, Integer> fullDistribution;
    private boolean initialized = false;
    private double[] bins;
    private double[] counts;
    private double averagePeasantProtectionProportion;
    private double medianPeasantProtectionProportion;
    private double modePeasantProtectionProportion;
    private List<VariablePopulationStatisticsRecord> variableStatisticsRecords;
    private double averageBanditNumberPeasantsToPreyUpon;
    private int modeBanditNumberPeasantsToPreyUpon;
    private double medianBanditNumberPeasantsToPreyUpon;
    private List<Integer> numbersOfPeasantsToPreyUpon;
    private double[] numbersOfPeasantsToPreyUponDoubles;
    private Map<Integer, Integer> numbersToPreyUpon;
    private List<String> peasantProportionHeadings;
    private Set<Entry<Double, Integer>> sortedFullDistributionEntries;
    private List<PeasantProportionRecordEntry> peasantProportionRecordEntries;

    public VariablePopulationProtectionStatistics(List<Bandit> bandits, List<Peasant> peasants, int numberBins,
            double interval) {
        super(bandits, peasants);
        variableStatisticsRecords = new ArrayList<VariablePopulationStatisticsRecord>();
        buildPeasantProtectionDistributions(numberBins, interval);
        initialized = true;
        calculateAdditionalStatistics();
    }

    @Override
    protected void calculateAdditionalStatistics() {
        if (!initialized)
            return;
        reloadPeasants();
        reloadBandits();
        calculatePeasantDistributions();
        calculateBanditDistributions();
    }

    private void reloadPeasants() {
        clearMap(distribution);
        clearMap(fullDistribution);
        loadPeasantProportionValuesToDistributions();
    }

    private void reloadBandits() {
        loadPredationBehaviorsForCalculation();
        buildMapOfNumberOfPeasantsToPreyUpon();
    }

    private void calculatePeasantDistributions() {
        if (peasants.size() == 0) {
            averagePeasantProtectionProportion = 0;
            modePeasantProtectionProportion = 0;
            medianPeasantProtectionProportion = 0;
        } else {
            calculateAveragePeasantProtectionProportion();
            calculateModePeasantProtectionProportion();
            calculateMedianPeasantProtectionProportion();
        }
    }

    private void calculateBanditDistributions() {

        if (bandits.size() == 0) {
            averageBanditNumberPeasantsToPreyUpon = 0;
            medianBanditNumberPeasantsToPreyUpon = 0;
            modeBanditNumberPeasantsToPreyUpon = 0;
        } else {
            calculateAverageBanditNumberPeasantsToPreyUpon();
            calculateMedianBanditNumberPeasantsToPreyUpon();
            calculateModeBanditNumberPeasantsToPreyUpon();
        }
    }

    private void buildPeasantProtectionDistributions(int numberBins, double interval) {
        distribution = new HashMap<Double, Integer>();
        fullDistribution = new HashMap<Double, Integer>();
        for (int i = 0; i < numberBins; i++) {
            fullDistribution.put(Util.roundDoubleToTwoDecimalPlaces(interval * i), 0);
        }
        buildPeasantProportionHeadings();
        //      loadPeasantProportionValuesToDistributions();
    }

    private void buildPeasantProportionHeadings() {
        peasantProportionHeadings = new ArrayList<String>();
        buildSortedFullDistributionEntries();
        Iterator<Entry<Double, Integer>> it = sortedFullDistributionEntries.iterator();
        String value = null;
        Entry<Double, Integer> currentEntry = null;
        while (it.hasNext()) {
            currentEntry = it.next();
            value = currentEntry.getKey().toString();
            peasantProportionHeadings.add("X" + value + "#");
            peasantProportionHeadings.add("X" + value + "%");
        }
    }

    protected void buildSortedFullDistributionEntries() {
        Set<Entry<Double, Integer>> entries = fullDistribution.entrySet();
        sortedFullDistributionEntries = new TreeSet<Entry<Double, Integer>>(new EntryComparator());
        sortedFullDistributionEntries.addAll(entries);
    }

    private void loadPeasantProportionValuesToDistributions() {
        Integer temp = null;
        Double bin = null;
        for (Peasant peasant : peasants) {
            bin = peasant.getRoundedProtectionProportion();
            temp = (distribution.get(bin) == null ? 1 : distribution.get(bin) + 1);
            distribution.put(bin, temp);
            fullDistribution.put(bin, temp);
        }
        buildPeasantProportionRecordEntries();
    }

    private void buildPeasantProportionRecordEntries() {
        peasantProportionRecordEntries = new ArrayList<PeasantProportionRecordEntry>();
        Iterator<String> it = peasantProportionHeadings.iterator();
        Iterator<Entry<Double, Integer>> itNumbers = sortedFullDistributionEntries.iterator();
        int total = peasants.size();
        while (it.hasNext()) {
            Double number = new Double(itNumbers.next().getValue());
            double proportion = (total != 0) ? number / total : 0;
            peasantProportionRecordEntries
                    .add(new PeasantProportionRecordEntry(it.next(), number.intValue(), it.next(), proportion));
        }

    }

    private void loadPredationBehaviorsForCalculation() {
        numbersOfPeasantsToPreyUpon = new ArrayList<Integer>();
        for (Bandit bandit : bandits) {
            numbersOfPeasantsToPreyUpon.add(((BehaviorBanditPreysOnMultiplePeasants) bandit.getPredationBehavior())
                    .getNumberOfPeasantsToPreyUpon()); // Fails whenever we add another PredationBehavior
        }
        numbersOfPeasantsToPreyUponDoubles = convertIntegerCollectionToDoublesArray(numbersOfPeasantsToPreyUpon);
    }

    private void calculateModeBanditNumberPeasantsToPreyUpon() {
        Set<Entry<Integer, Integer>> entries = numbersToPreyUpon.entrySet();
        Iterator<Entry<Integer, Integer>> it = entries.iterator();
        Entry<Integer, Integer> topEntry = it.next();
        Entry<Integer, Integer> currentEntry = null;
        while (it.hasNext()) {
            currentEntry = it.next();
            if (currentEntry.getValue() > topEntry.getValue())
                topEntry = currentEntry;
        }
        modeBanditNumberPeasantsToPreyUpon = topEntry.getKey();
    }

    private void calculateMedianBanditNumberPeasantsToPreyUpon() {
        Median median = new Median();
        medianBanditNumberPeasantsToPreyUpon = median.evaluate(numbersOfPeasantsToPreyUponDoubles);
    }

    private void calculateAverageBanditNumberPeasantsToPreyUpon() {
        Mean mean = new Mean();
        averageBanditNumberPeasantsToPreyUpon = mean.evaluate(numbersOfPeasantsToPreyUponDoubles);
    }

    private void clearMap(Map<Double, Integer> map) {
        for (Double key : map.keySet()) {
            map.put(key, 0);
        }
    }

    private void calculateAveragePeasantProtectionProportion() {
        Mean mean = new Mean();
        Double[] valuesDouble = new Double[distribution.keySet().size()];
        bins = unboxDoubleArray(distribution.keySet().toArray(valuesDouble));
        counts = convertIntegerCollectionToDoublesArray(distribution.values());
        averagePeasantProtectionProportion = mean.evaluate(bins, counts);
    }

    private double[] convertIntegerCollectionToDoublesArray(Collection<Integer> integers) {
        Iterator<Integer> it = integers.iterator();
        double[] doubles = new double[integers.size()];
        for (int i = 0; i < doubles.length; i++) {
            doubles[i] = it.next().doubleValue();
        }
        return doubles;
    }

    private double[] unboxDoubleArray(Double[] doubles) {
        double[] unboxedDoubles = new double[doubles.length];
        for (int i = 0; i < doubles.length; i++) {
            unboxedDoubles[i] = doubles[i];
        }
        return unboxedDoubles;
    }

    private void calculateMedianPeasantProtectionProportion() {
        double[] proportions = buildSortedArrayOfProtectionProportions();
        Median median = new Median();
        medianPeasantProtectionProportion = median.evaluate(proportions);
    }

    private double[] buildSortedArrayOfProtectionProportions() {
        List<Double> proportionsList = new ArrayList<Double>();
        for (Peasant peasant : peasants) {
            proportionsList.add(peasant.getRoundedProtectionProportion());
        }
        Double[] proportionsArray = new Double[peasants.size()];
        proportionsList.toArray(proportionsArray);
        double[] proportions = unboxDoubleArray(proportionsArray);
        Arrays.sort(proportions);
        return proportions;
    }

    private void calculateModePeasantProtectionProportion() {
        Set<Entry<Double, Integer>> entries = distribution.entrySet();
        Iterator<Entry<Double, Integer>> it = entries.iterator();
        Entry<Double, Integer> topEntry = it.next();
        Entry<Double, Integer> currentEntry = null;
        while (it.hasNext()) {
            currentEntry = it.next();
            if (currentEntry.getValue() > topEntry.getValue())
                topEntry = currentEntry;
        }
        modePeasantProtectionProportion = topEntry.getKey();
    }

    private void buildMapOfNumberOfPeasantsToPreyUpon() {
        numbersToPreyUpon = new HashMap<Integer, Integer>();
        for (int i = 0; i < ProtectionParameters.MAX_PEASANTS_TO_PREY_UPON; i++) {
            numbersToPreyUpon.put(i + 1, 0);
        }
        loadMapForEachBandit();
    }

    private void loadMapForEachBandit() {
        int subtotal = 0;
        for (Integer numberOfPeasantsToPreyUpon : numbersOfPeasantsToPreyUpon) {
            subtotal = numbersToPreyUpon.get(numberOfPeasantsToPreyUpon);
            subtotal++;
            numbersToPreyUpon.put(numberOfPeasantsToPreyUpon, subtotal);
        }
    }

    @Override
    protected void buildStatisticsRecord() {
        variableStatisticsRecords.add(new VariablePopulationStatisticsRecord(period, numberBandits, numberPeasants,
                averageBanditPayoff, averagePeasantPayoff, banditPeasantPayoffDelta, actorAdjustment,
                averagePeasantProtectionProportion, medianPeasantProtectionProportion,
                modePeasantProtectionProportion, averageBanditNumberPeasantsToPreyUpon,
                medianBanditNumberPeasantsToPreyUpon, modeBanditNumberPeasantsToPreyUpon,
                peasantProportionRecordEntries));
        logger.debug("statistics record added: " + variableStatisticsRecords.size());
    }

    public String printPeasantProtectionProportionDistribution() {
        StringBuffer sb = new StringBuffer();
        sb.append(Constants.CRLF);
        buildSortedFullDistributionEntries();
        Iterator<Entry<Double, Integer>> it = sortedFullDistributionEntries.iterator();
        Entry<Double, Integer> currentEntry = null;
        String oneDigit = null;
        while (it.hasNext()) {
            currentEntry = it.next();
            oneDigit = currentEntry.getKey().toString();
            sb.append(oneDigit);
            if (oneDigit.length() == 3)
                sb.append(" ");
            sb.append(": ");
            for (int i = 0; i < currentEntry.getValue(); i++) {
                sb.append("x");
            }
            sb.append(Constants.CRLF);
        }
        return sb.toString();
    }

    public String printBanditPredationEffortDistribution() {
        StringBuffer sb = new StringBuffer();
        sb.append(Constants.CRLF);
        for (int i = 0; i < ProtectionParameters.MAX_PEASANTS_TO_PREY_UPON; i++) {
            sb.append(i + 1);
            sb.append(" : ");
            numberPeasants = numbersToPreyUpon.get(i + 1);
            for (int j = 0; j < numberPeasants; j++) {
                sb.append("y");
            }
            sb.append(Constants.CRLF);
        }
        return sb.toString();
    }

    public double averagePeasantProtectionProportion() {
        return averagePeasantProtectionProportion;
    }

    public double modePeasantProtectionProportion() {
        return modePeasantProtectionProportion;
    }

    public double medianPeasantProtectionProportion() {
        return medianPeasantProtectionProportion;
    }

    @Override
    public List<? extends StatisticsRecord> getStatisticsRecords() {
        return variableStatisticsRecords;
    }

    public List<VariablePopulationStatisticsRecord> getVariableStatisticsRecords() {
        return variableStatisticsRecords;
    }

    public double averageBanditNumberPeasantsToPreyUpon() {
        return averageBanditNumberPeasantsToPreyUpon;
    }

    public int modeBanditNumberPeasantsToPreyUpon() {
        return modeBanditNumberPeasantsToPreyUpon;
    }

    public double medianBanditNumberPeasantsToPreyUpon() {
        return medianBanditNumberPeasantsToPreyUpon;
    }

    public List<String> getPeasantProportionHeadings() {
        return peasantProportionHeadings;
    }

    public List<PeasantProportionRecordEntry> getPeasantProportionRecordEntries() {
        return peasantProportionRecordEntries;
    }

    private class EntryComparator implements Comparator<Entry<Double, Integer>> {
        @Override
        public int compare(Entry<Double, Integer> paramT1, Entry<Double, Integer> paramT2) {

            return paramT1.getKey().compareTo(paramT2.getKey());
        }
    }
}