source: profile/src/main/java/geniusweb/profile/utilityspace/NumberValueSetUtilities.java

Last change on this file was 52, checked in by ruud, 14 months ago

Fixed small issues in domaineditor.

File size: 5.7 KB
Line 
1package geniusweb.profile.utilityspace;
2
3import java.math.BigDecimal;
4import java.math.RoundingMode;
5
6import com.fasterxml.jackson.annotation.JsonAutoDetect;
7import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
8import com.fasterxml.jackson.annotation.JsonCreator;
9import com.fasterxml.jackson.annotation.JsonProperty;
10
11import geniusweb.issuevalue.NumberValue;
12import geniusweb.issuevalue.NumberValueSet;
13import geniusweb.issuevalue.Value;
14import geniusweb.issuevalue.ValueSet;
15import tudelft.utilities.immutablelist.Range;
16
17/**
18 * The low and high values (from a {@link NumberValueSet} are given each a
19 * different utility. This linearly interpolates in-between utility values.
20 *
21 */
22@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)
23public class NumberValueSetUtilities implements ValueSetUtilities {
24
25 /** lowest possible value and utility at that point */
26 private final BigDecimal lowValue;
27 private final BigDecimal lowUtility;
28
29 /**
30 * highest possible value and utility at that point
31 */
32 private final BigDecimal highValue;
33 private final BigDecimal highUtility;
34
35 /**
36 *
37 * @param lowValue the low value of the {@link Range}
38 * @param lowUtility the utility of the {@link #lowValue}
39 * @param highValue the high value of the {@link Range}. Must be
40 * >lowValue.
41 * @param highUtility the utility of the {@link #highValue}
42 */
43 @JsonCreator
44 public NumberValueSetUtilities(
45 @JsonProperty("lowValue") BigDecimal lowValue,
46 @JsonProperty("lowUtility") BigDecimal lowUtility,
47 @JsonProperty("highValue") BigDecimal highValue,
48 @JsonProperty("highUtility") BigDecimal highUtility) {
49 if (lowValue == null || highValue == null || lowUtility == null
50 || highUtility == null) {
51 throw new NullPointerException(
52 "arguments lowValue, lowUtility, highValue and highUtility must be non-null");
53 }
54 if (!isInZeroOne(lowUtility)) {
55 throw new IllegalArgumentException("lowUtility must be in [0,1]");
56 }
57 if (!isInZeroOne(highUtility)) {
58 throw new IllegalArgumentException("highUtility must be in [0,1]");
59 }
60 if (highValue.compareTo(lowValue) <= 0) {
61 throw new IllegalArgumentException("highValue must be > lowValue");
62 }
63 this.lowValue = lowValue;
64 this.highValue = highValue;
65 this.lowUtility = lowUtility;
66 this.highUtility = highUtility;
67 }
68
69 @Override
70 public BigDecimal getUtility(Value value) {
71 if (!(value instanceof NumberValue)) {
72 return BigDecimal.ZERO;
73 }
74 BigDecimal x = ((NumberValue) value).getValue();
75 if (x.compareTo(lowValue) < 0 || x.compareTo(highValue) > 0)
76 return BigDecimal.ZERO;
77 // we need to be careful to avoid round errors from divides.
78 // so we return lowU + deltaU * (x-lowV) /deltaV
79 BigDecimal deltaU = highUtility.subtract(lowUtility);
80 BigDecimal deltaV = highValue.subtract(lowValue);
81
82 return lowUtility.add(deltaU.multiply(
83 x.subtract(lowValue).divide(deltaV, 8, RoundingMode.HALF_UP)));
84 }
85
86 @Override
87 public String isFitting(ValueSet valueset) {
88 if (!(valueset instanceof NumberValueSet)) {
89 return "The utilities are for a number valueset but the given values are "
90 + valueset;
91 }
92 NumberValueSet numvalset = (NumberValueSet) valueset;
93 if (numvalset.getRange().getLow().compareTo(lowValue) != 0) {
94 return "the utilities are specified down to " + lowValue
95 + " but the valueset starts at "
96 + numvalset.getRange().getLow();
97 }
98 if (numvalset.getRange().getHigh().compareTo(highValue) != 0) {
99 return "the utilities are specified up to " + highValue
100 + " but the valueset ends at "
101 + numvalset.getRange().getHigh();
102 }
103
104 return null;
105 }
106
107 /**
108 * @return the lowest value
109 */
110 public BigDecimal getLowValue() {
111 return lowValue;
112 }
113
114 /**
115 *
116 * @return the highest value
117 */
118 public BigDecimal getHighValue() {
119 return highValue;
120 }
121
122 /**
123 *
124 * @return the utility of the lowest value
125 */
126 public BigDecimal getLowUtility() {
127 return lowUtility;
128 }
129
130 /**
131 *
132 * @return the utility of the highest value
133 */
134 public BigDecimal getHighUtility() {
135 return highUtility;
136 }
137
138 @Override
139 public String toString() {
140 return "NumberValueSetUtilities(" + lowValue + "->" + lowUtility + ","
141 + highValue + "->" + highUtility + ")";
142 }
143
144 @Override
145 public int hashCode() {
146 final int prime = 31;
147 int result = 1;
148 result = prime * result
149 + ((highUtility == null) ? 0 : highUtility.hashCode());
150 result = prime * result
151 + ((highValue == null) ? 0 : highValue.hashCode());
152 result = prime * result
153 + ((lowUtility == null) ? 0 : lowUtility.hashCode());
154 result = prime * result
155 + ((lowValue == null) ? 0 : lowValue.hashCode());
156 return result;
157 }
158
159 @Override
160 public boolean equals(Object obj) {
161 if (this == obj)
162 return true;
163 if (obj == null)
164 return false;
165 if (getClass() != obj.getClass())
166 return false;
167 NumberValueSetUtilities other = (NumberValueSetUtilities) obj;
168 if (highUtility == null) {
169 if (other.highUtility != null)
170 return false;
171 } else if (!highUtility.equals(other.highUtility))
172 return false;
173 if (highValue == null) {
174 if (other.highValue != null)
175 return false;
176 } else if (!highValue.equals(other.highValue))
177 return false;
178 if (lowUtility == null) {
179 if (other.lowUtility != null)
180 return false;
181 } else if (!lowUtility.equals(other.lowUtility))
182 return false;
183 if (lowValue == null) {
184 if (other.lowValue != null)
185 return false;
186 } else if (!lowValue.equals(other.lowValue))
187 return false;
188 return true;
189 }
190
191 /**
192 * Check if value is in range [0,1]
193 *
194 * @param value
195 * @return true if in range.
196 */
197 private static boolean isInZeroOne(BigDecimal value) {
198 return value.compareTo(BigDecimal.ZERO) >= 0
199 && value.compareTo(BigDecimal.ONE) <= 0;
200
201 }
202
203}
Note: See TracBrowser for help on using the repository browser.