package geniusweb.profile.utilityspace;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import geniusweb.issuevalue.DiscreteValue;
import geniusweb.issuevalue.DiscreteValueSet;
import geniusweb.issuevalue.Value;
import geniusweb.issuevalue.ValueSet;
/**
* Links a set of values to utilities for that value. Does not link to some
* issue so may need further checking when used for an actual issue. Constructor
* guarantees that
*
* - All values in the provided map (the utilities) are in [0,1]
*
- All keys are proper {@link DiscreteValue}s
*
*/
@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)
public class DiscreteValueSetUtilities implements ValueSetUtilities {
private HashMap valueUtilities = new HashMap<>();
@SuppressWarnings("unused") // for deserializer
private DiscreteValueSetUtilities() {
}
/**
* create new object based on the given mapping from values to utilities.
*
* @param valueUtils map with key {@link DiscreteValue}s and value a Double
* in the range [0,1].
* @throws NullPointerException if one of the args is null
* @throws IllegalArgumentException if values are not in range [0,1].
*/
public DiscreteValueSetUtilities(
Map valueUtils) {
if (valueUtils == null) {
throw new NullPointerException("valueUtils==null");
}
if (valueUtils.keySet().contains(null)) {
throw new NullPointerException(
"one of the keys in valueUtils is null");
}
if (valueUtils.values().stream()
.anyMatch(v -> v == null || v.compareTo(BigDecimal.ZERO) < 0
|| v.compareTo(BigDecimal.ONE) > 0)) {
throw new IllegalArgumentException(
"Weights in valueUtils must all be in [0,1]");
}
this.valueUtilities.putAll(valueUtils);
}
@Override
public BigDecimal getUtility(Value value) {
if (!valueUtilities.containsKey(value)) {
return BigDecimal.ZERO;
}
return valueUtilities.get(value);
}
/**
* @return copy of the value-utility pair map.
*/
public Map getUtilities() {
return Collections.unmodifiableMap(valueUtilities);
}
@Override
public String isFitting(ValueSet valueset) {
if (!(valueset instanceof DiscreteValueSet)) {
return "The utilities are for a discrete valueset but the given values are "
+ valueset;
}
DiscreteValueSet discvalueset = (DiscreteValueSet) valueset;
if (!valueUtilities.keySet()
.equals(new HashSet<>(discvalueset.getValues())))
return "The values in the set " + valueset
+ " do not match the values mapped to utilities "
+ valueUtilities.keySet();
return null;
}
@Override
public String toString() {
return "DiscreteValueSetUtilities" + valueUtilities;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((valueUtilities == null) ? 0 : valueUtilities.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DiscreteValueSetUtilities other = (DiscreteValueSetUtilities) obj;
if (valueUtilities == null) {
if (other.valueUtilities != null)
return false;
} else if (!valueUtilities.equals(other.valueUtilities))
return false;
return true;
}
}