com.cogpunk.math.probability.ConditionalReevaluationProbabilityProfile Maven / Gradle / Ivy
Show all versions of cogpunk-math Show documentation
package com.cogpunk.math.probability;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import com.cogpunk.math.NumberOperator;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.EqualsBuilder;
/**
* Conditionally re-evaluates the probabilities under conditions defined by the supplied the Event selector
*
* An example would be a conditional re-roll of dice
*/
public class ConditionalReevaluationProbabilityProfile implements EventProbabilityProfile {
private EventProbabilityProfile profile;
/**
* @param baseProfile The base, source profile
* @param selector The event selector that determines which event are to be reevaluated
* @param reevaluationCount The maximum number of times a reevaluation is to occur
* @param numberOperator The operator for the probability number type
*/
public ConditionalReevaluationProbabilityProfile(EventProbabilityProfile baseProfile, EventSelector selector, int reevaluationCount, NumberOperator numberOperator) {
super();
profile = calculate(baseProfile, selector, reevaluationCount, numberOperator);
}
private EventProbabilityProfile calculate(EventProbabilityProfile baseProfile, EventSelector selector, int reevaluationCount, NumberOperator numberOperator) {
Map currentMap = new HashMap();
currentMap.putAll(baseProfile.map());
Set reevalEvents = selector.selectEvents(baseProfile);
for (int n = 0; n < reevaluationCount; n++) {
P totalReevalProb = numberOperator.cast(0);
for (E event : reevalEvents) {
P prob = currentMap.get(event);
currentMap.remove(event);
totalReevalProb = numberOperator.add(totalReevalProb, prob);
}
// Take the base profile, multiply it by the probability of revelaution and add it to the current profile
Map reevalMap = new HashMap();
reevalMap.putAll(baseProfile.map());
for (E event : reevalMap.keySet()) {
P prob = numberOperator.multiply(totalReevalProb, reevalMap.get(event));
if (!currentMap.containsKey(event)) {
currentMap.put(event, prob);
} else {
currentMap.put(event, numberOperator.add(prob, currentMap.get(event)));
}
}
}
return new SimpleProbabilityProfileImpl(currentMap);
}
@Override
public P getProbability(E event) {
return profile.getProbability(event);
}
@Override
public Map map() {
return profile.map();
}
@Override
public boolean equals(final Object other) {
if (!(other instanceof ConditionalReevaluationProbabilityProfile)) {
return false;
}
ConditionalReevaluationProbabilityProfile, ?> castOther = (ConditionalReevaluationProbabilityProfile, ?>) other;
return new EqualsBuilder().append(profile, castOther.profile).isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder().append(profile).toHashCode();
}
}