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

Last change on this file since 30 was 30, checked in by bart, 3 years ago

Fixed memory leak. MOPAC2. removed jcenter build dependencies

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