source: profile/src/test/java/geniusweb/profile/utilityspace/SumOfGroupsUtilitySpaceTest.java@ 52

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

Fixed small issues in domaineditor.

File size: 10.5 KB
Line 
1package geniusweb.profile.utilityspace;
2
3import static org.junit.Assert.assertEquals;
4import static org.junit.Assert.assertTrue;
5
6import java.io.IOException;
7import java.math.BigDecimal;
8import java.math.BigInteger;
9import java.nio.charset.StandardCharsets;
10import java.nio.file.Files;
11import java.nio.file.Paths;
12import java.util.ArrayList;
13import java.util.Arrays;
14import java.util.Collections;
15import java.util.HashMap;
16import java.util.List;
17import java.util.Map;
18import java.util.stream.Collectors;
19
20import org.junit.Before;
21import org.junit.Test;
22
23import com.fasterxml.jackson.core.JsonProcessingException;
24import com.fasterxml.jackson.databind.ObjectMapper;
25
26import geniusweb.issuevalue.Bid;
27import geniusweb.issuevalue.DiscreteValue;
28import geniusweb.issuevalue.DiscreteValueSet;
29import geniusweb.issuevalue.Domain;
30import geniusweb.issuevalue.Value;
31import geniusweb.issuevalue.ValueSet;
32import geniusweb.profile.Profile;
33import tudelft.utilities.immutablelist.AbstractImmutableList;
34import tudelft.utilities.immutablelist.ImmutableList;
35import tudelft.utilities.immutablelist.Outer;
36
37public class SumOfGroupsUtilitySpaceTest {
38 private final ObjectMapper jackson = new ObjectMapper();
39 private SumOfGroupsUtilitySpace pa1;
40 private final String iss1 = "issue1", iss2 = "issue2", iss3 = "issue3";
41 private static BigDecimal N01 = new BigDecimal("0.1"),
42 N02 = new BigDecimal("0.2"), N03 = new BigDecimal("0.3"),
43 N05 = new BigDecimal("0.5"), N07 = new BigDecimal("0.7"),
44 N08 = new BigDecimal("0.8"), N09 = new BigDecimal("0.9");
45
46 private final DiscreteValue lo = new DiscreteValue("low");
47 private final DiscreteValue hi = new DiscreteValue("high");
48 private final Bid resBid = new Bid(iss1, hi);
49
50 private Domain domain;
51 private PartsUtilities putils12, putils3;
52 private String serialized = "{\"SumOfGroupsUtilitySpace\":{\"domain\":{\"name\":\"domain\",\"issuesValues\":{\"issue3\":{\"values\":[\"low\",\"high\"]},\"issue2\":{\"values\":[\"low\",\"high\"]},\"issue1\":{\"values\":[\"low\",\"high\"]}}},\"name\":\"testspace\",\"partUtilities\":{\"1and2\":{\"PartsUtilities\":{\"issues\":[\"issue1\",\"issue2\"],\"utilslist\":[{\"values\":[\"low\",\"low\"],\"util\":0.16},{\"values\":[\"high\",\"high\"],\"util\":0.72},{\"values\":[\"low\",\"high\"],\"util\":0.16},{\"values\":[\"high\",\"low\"],\"util\":0.16}]}},\"3\":{\"PartsUtilities\":{\"issues\":[\"issue3\"],\"utilslist\":[{\"values\":[\"low\"],\"util\":0.16},{\"values\":[\"high\"],\"util\":0.14}]}}},\"reservationbid\":{\"issuevalues\":{\"issue1\":\"high\"}}}}";
53
54 @Before
55 public void before() {
56 Map<String, ValueSet> issues = new HashMap<>();
57 issues.put(iss1, new DiscreteValueSet(lo, hi));
58 issues.put(iss2, new DiscreteValueSet(lo, hi));
59 issues.put(iss3, new DiscreteValueSet(lo, hi));
60 domain = new Domain("domain", issues);
61
62 Map<ProductOfValue, BigDecimal> utils12 = new HashMap<>();
63 // util12 has weight N08
64 utils12.put(new ProductOfValue(Arrays.asList(lo, lo)),
65 N02.multiply(N08));
66 utils12.put(new ProductOfValue(Arrays.asList(lo, hi)),
67 N02.multiply(N08));
68 utils12.put(new ProductOfValue(Arrays.asList(hi, lo)),
69 N02.multiply(N08));
70 utils12.put(new ProductOfValue(Arrays.asList(hi, hi)),
71 N09.multiply(N08));
72 putils12 = new PartsUtilities(Arrays.asList(iss1, iss2), utils12);
73
74 // utils3 has weight N02.
75 Map<ProductOfValue, BigDecimal> utils3 = new HashMap<>();
76 utils3.put(new ProductOfValue(Arrays.asList(lo)), N08.multiply(N02));
77 utils3.put(new ProductOfValue(Arrays.asList(hi)), N07.multiply(N02));
78 putils3 = new PartsUtilities(Arrays.asList(iss3), utils3);
79
80 }
81
82 @Test(expected = IllegalArgumentException.class)
83 public void smokeTestIncompleteProfile() {
84 HashMap<String, PartsUtilities> partutils = new HashMap<>();
85 partutils.put("1and2", putils12);
86 new SumOfGroupsUtilitySpace(domain, "testspace", partutils, resBid);
87
88 }
89
90 @Test // non-normalized utils should be fine in this case
91 public void smokeTestWeightsNotNormalized() {
92 HashMap<String, PartsUtilities> partutils = new HashMap<>();
93 partutils.put("1and2", putils12);
94 partutils.put("3", putils3);
95 new SumOfGroupsUtilitySpace(domain, "testspace", partutils, resBid);
96
97 }
98
99 @Test(expected = IllegalArgumentException.class)
100 public void smokeTestExtraIssue() {
101 HashMap<String, PartsUtilities> partutils = new HashMap<>();
102 partutils.put("1and2", putils12);
103 partutils.put("3", putils3);
104 partutils.put("4", putils3);
105 new SumOfGroupsUtilitySpace(domain, "testspace", partutils, resBid);
106
107 }
108
109 @Test
110 public void smokeTest() {
111 makeBasic();
112 }
113
114 @Test
115 public void testName() {
116 SumOfGroupsUtilitySpace paus = makeBasic();
117 assertEquals("testspace", paus.getName());
118 }
119
120 @Test
121 public void testDomain() {
122 SumOfGroupsUtilitySpace paus = makeBasic();
123 assertEquals(domain, paus.getDomain());
124 }
125
126 @Test
127 public void testGetResBid() {
128 SumOfGroupsUtilitySpace paus = makeBasic();
129 assertEquals(resBid, paus.getReservationBid());
130 }
131
132 @Test
133 public void testGetUtilityEmptyBid() {
134 SumOfGroupsUtilitySpace paus = makeBasic();
135 assertTrue(BigDecimal.ZERO.compareTo(
136 paus.getUtility(new Bid(Collections.emptyMap()))) == 0);
137 }
138
139 @Test
140 public void testGetUtility() {
141 SumOfGroupsUtilitySpace paus = makeBasic();
142 Map<String, Value> map = new HashMap<>();
143 map.put(iss1, lo);
144 map.put(iss2, lo); // 1,2 combined has util 0.2
145 map.put(iss3, hi); // 3 has util 0.7
146 // weights are set to 0.8, 0.2. Gives total util 0.3
147 Bid bid = new Bid(map);
148 assertTrue(N03.compareTo(paus.getUtility(bid)) == 0);
149 }
150
151 /**
152 * Demonstrates how to convert {@link LinearAdditiveUtilitySpace} to a
153 * {@link SumOfGroupsUtilitySpace}
154 *
155 */
156 @Test
157 public void testConvertLas() throws IOException {
158 String profile = new String(
159 Files.readAllBytes(Paths.get("src/test/resources/party1.json")),
160 StandardCharsets.UTF_8);
161 LinearAdditiveUtilitySpace las = jackson.readValue(profile,
162 LinearAdditiveUtilitySpace.class);
163 SumOfGroupsUtilitySpace pas = new SumOfGroupsUtilitySpace(las);
164 checkUtilitiesAllEqual(las, pas);
165 System.out.println("Generated partial profile:\n" + pas);
166 }
167
168 /**
169 * Demonstrates how to convert {@link LinearAdditiveUtilitySpace} to a
170 * {@link SumOfGroupsUtilitySpace} and group some issues
171 *
172 */
173 @Test
174 public void testConvertAndGroupParty() throws IOException {
175 String profile = new String(
176 Files.readAllBytes(Paths.get("src/test/resources/party1.json")),
177 StandardCharsets.UTF_8);
178 LinearAdditiveUtilitySpace las = jackson.readValue(profile,
179 LinearAdditiveUtilitySpace.class);
180 SumOfGroupsUtilitySpace pas = new SumOfGroupsUtilitySpace(las);
181 pas = pas.group(Arrays.asList("Food", "Drinks"), "food&drinks");
182 checkUtilitiesAllEqual(las, pas);
183 System.out.println("Re-grouped party profile:\n");
184 System.out.println(jackson.writeValueAsString(pas));
185
186 }
187
188 @Test
189 public void testGroupe2e() {
190 Map<ProductOfValue, BigDecimal> utils1 = new HashMap<>();
191 utils1.put(new ProductOfValue(Arrays.asList(lo)), N02.multiply(N02));
192 utils1.put(new ProductOfValue(Arrays.asList(hi)), N03.multiply(N02));
193 Map<ProductOfValue, BigDecimal> utils2 = new HashMap<>();
194 utils2.put(new ProductOfValue(Arrays.asList(lo)), N07.multiply(N03));
195 utils2.put(new ProductOfValue(Arrays.asList(hi)), N02.multiply(N03));
196 Map<ProductOfValue, BigDecimal> utils3 = new HashMap<>();
197 utils3.put(new ProductOfValue(Arrays.asList(lo)), N05.multiply(N05));
198 utils3.put(new ProductOfValue(Arrays.asList(hi)), N08.multiply(N05));
199 HashMap<String, PartsUtilities> partutils = new HashMap<>();
200 partutils.put(iss1, new PartsUtilities(Arrays.asList(iss1), utils1));
201 partutils.put(iss2, new PartsUtilities(Arrays.asList(iss2), utils2));
202 partutils.put(iss3, new PartsUtilities(Arrays.asList(iss3), utils3));
203
204 Map<String, ValueSet> issvalues = new HashMap<>();
205 issvalues.put(iss1, new DiscreteValueSet(lo, hi));
206 issvalues.put(iss2, new DiscreteValueSet(lo, hi));
207 issvalues.put(iss3, new DiscreteValueSet(lo, hi));
208 Domain domain1 = new Domain("test", issvalues);
209
210 SumOfGroupsUtilitySpace pas = new SumOfGroupsUtilitySpace(domain1,
211 "testspace", partutils, resBid);
212
213 SumOfGroupsUtilitySpace pasgrouped12 = pas
214 .group(Arrays.asList(iss1, iss2), "iss12");
215
216 checkEqualUtilities(pas, pasgrouped12);
217
218 }
219
220 @Test
221 public void testSerialize() throws JsonProcessingException {
222 SumOfGroupsUtilitySpace paus = makeBasic();
223 ObjectMapper jackson = new ObjectMapper();
224 String string = jackson.writeValueAsString(paus);
225 System.out.println(string);
226 assertEquals(serialized, string);
227
228 }
229
230 @Test
231 public void testDeserialize() throws IOException {
232 ObjectMapper jackson = new ObjectMapper();
233 assertEquals(makeBasic(), jackson.readValue(serialized, Profile.class));
234
235 }
236
237 /************************ PRIVATE FUNCTIONS *******************/
238
239 private void checkEqualUtilities(UtilitySpace space1, UtilitySpace space2) {
240 for (Bid bid : new MyAllBidsList(space1.getDomain())) {
241 assertEquals(space1.getUtility(bid), space2.getUtility(bid));
242 }
243 }
244
245 private SumOfGroupsUtilitySpace makeBasic() {
246 HashMap<String, PartsUtilities> partutils = new HashMap<>();
247 partutils.put("1and2", putils12);
248 partutils.put("3", putils3);
249 return new SumOfGroupsUtilitySpace(domain, "testspace", partutils,
250 resBid);
251
252 }
253
254 private void checkUtilitiesAllEqual(UtilitySpace space1,
255 UtilitySpace space2) {
256 for (Bid bid : new MyAllBidsList(space1.getDomain())) {
257 assertTrue(space1.getUtility(bid)
258 .compareTo(space2.getUtility(bid)) == 0);
259 }
260 }
261
262}
263
264/**
265 * Copy of AllBidsList. We can not depend on BidSpace because that would cause a
266 * cyclic dependency.
267 */
268class MyAllBidsList extends AbstractImmutableList<Bid> {
269
270 private final List<String> issues;
271 private final Outer<? extends Value> allValuePermutations;
272
273 /**
274 * A list containing all bids in the space. This is an ImmutableList so it
275 * can contain all bids without pre-computing them.
276 *
277 */
278 public MyAllBidsList(Domain domain) {
279 if (domain == null)
280 throw new IllegalArgumentException("domain=null");
281 issues = new ArrayList<>(domain.getIssues());
282
283 List<ImmutableList<Value>> values = issues.stream()
284 .map(issue -> domain.getValues(issue))
285 .collect(Collectors.toList());
286
287 allValuePermutations = new Outer<Value>(values);
288 }
289
290 @Override
291 public Bid get(BigInteger index) {
292 ImmutableList<? extends Value> nextValues = allValuePermutations
293 .get(index);
294
295 Map<String, Value> issueValues = new HashMap<>();
296 for (int n = 0; n < issues.size(); n++) {
297 issueValues.put(issues.get(n),
298 nextValues.get(BigInteger.valueOf(n)));
299 }
300 return new Bid(issueValues);
301 }
302
303 @Override
304 public BigInteger size() {
305 return allValuePermutations.size();
306 }
307
308}
Note: See TracBrowser for help on using the repository browser.