Changeset 4
- Timestamp:
- 09/18/19 10:00:22 (5 years ago)
- Files:
-
- 13 added
- 25 edited
Legend:
- Unmodified
- Added
- Removed
-
bidspace/pom.xml
r2 r4 140 140 <target>1.8</target> 141 141 </configuration> 142 </plugin> 143 <plugin> 144 <groupId>org.apache.maven.plugins</groupId> 145 <artifactId>maven-source-plugin</artifactId> 146 <executions> 147 <execution> 148 <id>attach-sources</id> 149 <goals> 150 <goal>jar</goal> 151 </goals> 152 </execution> 153 </executions> 142 154 </plugin> 143 155 -
bidspace/src/main/java/geniusweb/bidspace/BidsWithUtility.java
r2 r4 3 3 import java.math.BigDecimal; 4 4 import java.math.BigInteger; 5 import java.util. ArrayList;6 import java.util. LinkedList;5 import java.util.Collections; 6 import java.util.HashMap; 7 7 import java.util.List; 8 import java.util.Map; 9 import java.util.stream.Collectors; 8 10 9 11 import geniusweb.issuevalue.Bid; 12 import geniusweb.issuevalue.Domain; 13 import geniusweb.issuevalue.Value; 10 14 import geniusweb.profile.utilityspace.LinearAdditiveUtilitySpace; 11 15 import tudelft.utilities.immutablelist.AbstractImmutableList; 16 import tudelft.utilities.immutablelist.FixedList; 17 import tudelft.utilities.immutablelist.ImmutableList; 18 import tudelft.utilities.immutablelist.JoinedList; 19 import tudelft.utilities.immutablelist.MapList; 20 import tudelft.utilities.immutablelist.Tuple; 12 21 13 22 /** 14 * Object containing a subset of all bids, that have utility within given range. 23 * Tool class containing functions dealing with utilities of all bids in a given 24 * {@link LinearAdditiveUtilitySpace}. This class caches previously computed 25 * values to accelerate the calls and subsequent calls. Re-use the object to 26 * keep/reuse the cache. 15 27 */ 16 public class BidsWithUtility extends AbstractImmutableList<Bid> { 17 18 private final List<Bid> collectedbids; 19 20 /** 21 * Create Bids with utility within given bounds. 22 * 23 * @param space the {@link LinearAdditiveUtilitySpace} to search 24 * @param min the minimum required utility 25 * @param max the maximum required utility 26 */ 27 public BidsWithUtility(LinearAdditiveUtilitySpace space, BigDecimal min, BigDecimal max) { 28 this.collectedbids = new ArrayList<Bid>(getBids(space, min, max)); 29 } 30 31 /** 32 * Brute force hack for this time. Maybe we can construct this in a lazy way. 33 * 34 * @param space 35 * @param min 36 * @param max 37 * @return 38 */ 39 private List<Bid> getBids(LinearAdditiveUtilitySpace space, BigDecimal min, BigDecimal max) { 40 List<Bid> goodbids = new LinkedList<Bid>(); 41 for (Bid bid : new AllBidsList(space.getDomain())) { 42 BigDecimal util = space.getUtility(bid); 43 if (util.compareTo(min) >= 0 && util.compareTo(max) <= 0) { 44 goodbids.add(bid); 45 } 46 } 47 return goodbids; 28 public class BidsWithUtility { 29 30 private final List<IssueInfo> issueInfo; 31 private final int precision; // #digits used for Intervals 32 33 /** 34 * cache. Key = call arguments for {@link #get(int, Interval)}. Value=return 35 * value of that call. 36 */ 37 private final Map<Tuple<Integer, Interval>, ImmutableList<Bid>> cache = new HashMap<>(); 38 39 /** 40 * Default constructor, uses default precision 6. This value seems practical 41 * for the common range of issues, utilities and weights. See 42 * {@link #BidsWithUtil(LinearAdditiveUtilitySpace, int)} for more details 43 * on the precision. 44 * 45 * @param space the {@link LinearAdditiveUtilitySpace} to analyze 46 */ 47 public BidsWithUtility(LinearAdditiveUtilitySpace space) { 48 this(space, 6); 49 } 50 51 /** 52 * 53 * @param space the {@link LinearAdditiveUtilitySpace} to analyze 54 * @param precision the number of digits to use for computations. This value 55 * should match the max number of (digits used in the 56 * weight of an issue + number of digits used in the issue 57 * utility). Usually you also look at the step size, and 58 * the range of interest. For instance if your utility 59 * function has values 1/3 and 2/3, then these have an 60 * 'infinite' number of relevant digits. But if we want to 61 * search bids between utility 0.1 and 0.2, then computing 62 * in 2 digits might already be sufficient. This algorithm 63 * has memory and space complexity O( |nissues| 64 * 10^precision ). For spaces up to 7 issues, 7 digits 65 * should be feasible; for 9 issues, 6 digits may be the 66 * maximum. 67 */ 68 public BidsWithUtility(LinearAdditiveUtilitySpace space, int precision) { 69 this(getInfo(space, precision), precision); 70 } 71 72 /** 73 * 74 * @param issuesInfo List of the relevant issues (in order of relevance) and 75 * all info of each issue. 76 * @param precision the number of digits used in Intervals. 77 */ 78 public BidsWithUtility(List<IssueInfo> issuesInfo, int precision) { 79 if (issuesInfo == null || issuesInfo.isEmpty()) { 80 throw new IllegalArgumentException( 81 "sortedissues list must contain at least 1 element"); 82 } 83 84 this.issueInfo = issuesInfo; 85 this.precision = precision; 86 87 } 88 89 /** 90 * @return the utility {@link Interval} of this space: minimum and maximum 91 * achievable utility. 92 */ 93 public Interval getRange() { 94 return getRange(issueInfo.size() - 1); 95 } 96 97 /** 98 * 99 * @param range the minimum and maximum utility required of the bids. to be 100 * included (both ends inclusive). 101 * @return a list with bids that have utility inside range. possibly empty. 102 * With decreasing precision, more bids may drop out due to rounding 103 * errors. 104 */ 105 public ImmutableList<Bid> getBids(Interval range) { 106 return get(issueInfo.size() - 1, range.round(precision)); 107 } 108 109 public List<IssueInfo> getInfo() { 110 return Collections.unmodifiableList(issueInfo); 111 } 112 113 /** 114 * Create partial BidsWithUtil list considering only issues 0..n, with 115 * utilities in given range. 116 * 117 * @param n the number of {@link #issueRanges} to consider, we consider 118 * 0..n here. The recursion decreases n until n=0 119 * @param goal the minimum and maximum utility required of the bids. to be 120 * included (both ends inclusive) 121 * @return BidsWithUtil list, possibly empty. 122 */ 123 protected ImmutableList<Bid> get(int n, Interval goal) { 124 if (goal == null) { 125 throw new NullPointerException("Interval=null"); 126 } 127 128 // clamp goal into what is reachable. Avoid caching empty 129 goal = goal.intersect(getRange(n)); 130 if (goal.isEmpty()) { 131 return new FixedList<>(); 132 } 133 134 Tuple<Integer, Interval> cachetuple = new Tuple<>(n, goal); 135 ImmutableList<Bid> cached = cache.get(cachetuple); 136 if (cached != null) { 137 // hits++; 138 return cached; 139 } 140 141 ImmutableList<Bid> result = checkedGet(n, goal); 142 cache.put(cachetuple, result); 143 return result; 144 } 145 146 private static List<IssueInfo> getInfo(LinearAdditiveUtilitySpace space2, 147 int precision) { 148 Domain dom = space2.getDomain(); 149 return space2.getDomain().getIssues().stream() 150 .map(issue -> new IssueInfo(issue, dom.getValues(issue), 151 space2.getUtilities().get(issue), 152 space2.getWeight(issue), precision)) 153 .collect(Collectors.toList()); 154 } 155 156 private ImmutableList<Bid> checkedGet(int n, Interval goal) { 157 IssueInfo info = issueInfo.get(n); 158 // issue is the first issuesWithRange. 159 String issue = issueInfo.get(n).getName(); 160 161 if (n == 0) 162 return new OneIssueSubset(info, goal); 163 164 // make new list, joining all sub-lists 165 ImmutableList<Bid> fulllist = new FixedList<>(); 166 for (Value val : info.getValues()) { 167 BigDecimal weightedutil = info.getWeightedUtil(val); 168 Interval subgoal = goal.subtract(weightedutil); 169 // recurse: get list of bids for the subspace 170 ImmutableList<Bid> partialbids = get(n - 1, subgoal); 171 172 Bid bid = new Bid(issue, val); 173 ImmutableList<Bid> fullbids = new MapList<Bid, Bid>( 174 pbid -> pbid.merge(bid), partialbids); 175 if (!fullbids.size().equals(BigInteger.ZERO)) 176 fulllist = new JoinedList<Bid>(fullbids, fulllist); 177 } 178 return fulllist; 179 } 180 181 /** 182 * @param n the maximum issuevalue utility to include. Use n=index of last 183 * issue s= (#issues in the domain - 1) for the full range of this 184 * domain. 185 * @return Interval (min, max) of the total weighted utility Interval of 186 * issues 0..n. All weighted utilities have been rounded to the set 187 * {@link #precision} 188 */ 189 private Interval getRange(int n) { 190 Interval value = Interval.ZERO; 191 for (int i = 0; i <= n; i++) { 192 value = value.add(issueInfo.get(i).getInterval()); 193 } 194 return value; 195 } 196 197 } 198 199 /** 200 * List of all one-issue bids that have utility inside given interval. 201 */ 202 class OneIssueSubset extends AbstractImmutableList<Bid> { 203 private final IssueInfo info; 204 private final Interval interval; 205 private BigInteger size; 206 207 /** 208 * 209 * @param info the {@link IssueInfo} 210 * @param interval a utility interval (weighted) 211 */ 212 OneIssueSubset(IssueInfo info, Interval interval) { 213 this.info = info; 214 this.interval = interval; 215 this.size = BigInteger.valueOf(info.subsetSize(interval)); 48 216 } 49 217 50 218 @Override 51 219 public Bid get(BigInteger index) { 52 return collectedbids.get(index.intValue()); 220 return new Bid(info.getName(), 221 info.subset(interval).get(index.intValue())); 53 222 } 54 223 55 224 @Override 56 225 public BigInteger size() { 57 return BigInteger.valueOf(collectedbids.size());226 return size; 58 227 } 59 228 -
bidspace/src/test/java/geniusweb/bidspace/BidsWithUtilityTest.java
r2 r4 1 1 package geniusweb.bidspace; 2 2 3 import static org.junit.Assert.assertEquals; 4 import static org.mockito.Matchers.any; 5 import static org.mockito.Mockito.mock; 6 import static org.mockito.Mockito.when; 3 import static org.junit.Assert.assertTrue; 7 4 8 5 import java.io.IOException; 9 6 import java.math.BigDecimal; 10 7 import java.math.BigInteger; 8 import java.math.RoundingMode; 11 9 import java.nio.file.Files; 12 10 import java.nio.file.Paths; 11 import java.util.Arrays; 13 12 import java.util.Collection; 14 import java.util.HashMap; 15 import java.util.LinkedList; 16 import java.util.Map; 13 import java.util.Random; 17 14 18 import org.junit.Before;19 15 import org.junit.Test; 16 import org.junit.runner.RunWith; 17 import org.junit.runners.Parameterized; 18 import org.junit.runners.Parameterized.Parameters; 20 19 21 20 import com.fasterxml.jackson.databind.ObjectMapper; 22 21 23 22 import geniusweb.issuevalue.Bid; 24 import geniusweb.issuevalue.DiscreteValue;25 import geniusweb.issuevalue.DiscreteValueSet;26 import geniusweb.issuevalue.Domain;27 import geniusweb.issuevalue.NumberValue;28 import geniusweb.issuevalue.NumberValueSet;29 import geniusweb.issuevalue.ValueSet;30 23 import geniusweb.profile.Profile; 31 24 import geniusweb.profile.utilityspace.LinearAdditiveUtilitySpace; 25 import tudelft.utilities.immutablelist.ImmutableList; 32 26 27 @RunWith(Parameterized.class) 33 28 public class BidsWithUtilityTest { 34 private static final DiscreteValue I1V2 = new DiscreteValue("i1v2"); 35 private static final DiscreteValue I1V1 = new DiscreteValue("i1v1"); 36 private static final NumberValue I2V1 = new NumberValue("2.00"); 37 private static final NumberValue I2V2 = new NumberValue("2.45"); 38 private static final NumberValue I2V3 = new NumberValue("2.90"); 39 private static final String DOMAINNAME = "testdomain"; 40 private static final String ISSUE1 = "issue1"; 41 private static final String ISSUE2 = "issue2"; 42 private static final Map<String, ValueSet> issues = new HashMap<>(); 29 private final static ObjectMapper jackson = new ObjectMapper(); 30 private final Interval utilityGoal = new Interval(new BigDecimal("0.50"), 31 new BigDecimal("0.51")); 32 private LinearAdditiveUtilitySpace profile; 33 private long expectedSize; 34 private int accuracy = 5; 43 35 44 private static ValueSet values1; 45 private static ValueSet values2; 46 private static final BigDecimal TWO = new BigDecimal("2"); 47 private static final BigDecimal THREE = new BigDecimal("3"); 48 private final static BigDecimal ZERO_1 = new BigDecimal("0.1"), ZERO_2 = new BigDecimal("0.2"), 49 ZERO_3 = new BigDecimal("0.3"); 36 @Parameters 37 public static Collection<Object[]> data() { 38 return Arrays.asList(new Object[][] { 39 { "src/test/resources/jobs/jobs1.json", 11 }, 40 { "src/test/resources/7issues/7issues1.json", 260000 }, 41 { "src/test/resources/9issues/9issues1.json", 25000000 } }); 42 } 50 43 51 private static Domain domain; 52 private final static ObjectMapper jackson = new ObjectMapper(); 44 public BidsWithUtilityTest(String filename, long expectedsize) 45 throws IOException { 46 String file = new String(Files.readAllBytes(Paths.get(filename))); 47 profile = (LinearAdditiveUtilitySpace) jackson.readValue(file, 48 Profile.class); 49 this.expectedSize = expectedsize; 50 } 53 51 54 @Before 55 public void before() { 56 Collection<DiscreteValue> discretevalues1 = new LinkedList<>(); 57 discretevalues1.add(I1V1); 58 discretevalues1.add(I1V2); 59 values1 = new DiscreteValueSet(discretevalues1); 60 issues.put(ISSUE1, values1); 61 62 values2 = new NumberValueSet(TWO, THREE, new BigDecimal("0.45")); 63 issues.put(ISSUE2, values2); 64 65 domain = new Domain(DOMAINNAME, issues); 52 /** 53 * Test if the values are within acceptable range from the goal. 54 */ 55 @Test 56 public void test() { 57 ImmutableList<Bid> list = new BidsWithUtility(profile, accuracy) 58 .getBids(utilityGoal); 59 Random rand = new Random(); 60 // check not all but only 10000 random bids as list may be way too large 61 // to test them all. Testing 1 billion bids may take 15 minutes or so on 62 // quad core i7 @2.4GHz..... 63 // also notice that we may be checking only part of the list if 64 // the size of the list would become bigger than maxint. 65 for (int n = 0; n < 10000; n++) { 66 Bid bid = list.get(rand.nextInt(list.size().intValue())); 67 assertTrue(utilityGoal.contains(profile.getUtility(bid) 68 .setScale(accuracy - 1, RoundingMode.HALF_UP))); 69 } 70 assertTrue( 71 list.size().compareTo(BigInteger.valueOf(expectedSize)) >= 0); 66 72 67 73 } 68 74 69 75 @Test 70 public void smokeTest() { 71 LinearAdditiveUtilitySpace space = mock(LinearAdditiveUtilitySpace.class); 72 when(space.getDomain()).thenReturn(domain); 73 when(space.getUtility(any(Bid.class))).thenReturn(ZERO_2); 74 new BidsWithUtility(space, new BigDecimal("0.1"), new BigDecimal("0.3")); 76 public void testMaxUtil() { 77 BidsWithUtility bidswithutil = new BidsWithUtility(profile); 78 // notice, this is the *rounded* max util 79 BigDecimal maxutil = bidswithutil.getRange().getMax(); 80 Interval goal = new Interval( 81 maxutil.subtract(new BigDecimal("0.00001")), maxutil); 82 83 ImmutableList<Bid> bidsnearmax = bidswithutil.getBids(goal); 84 assertTrue(bidsnearmax.size() != BigInteger.ZERO); 85 86 BigDecimal foundmax = BigDecimal.ZERO; 87 for (Bid bid : bidsnearmax) { 88 BigDecimal util = profile.getUtility(bid); 89 if (util.compareTo(foundmax) > 0) { 90 foundmax = util; 91 } 92 } 93 // found maximum may be slightly lower or higher because we rounded 94 // all weighted utilities. 95 assertTrue(Math 96 .abs(foundmax.doubleValue() - maxutil.doubleValue()) < 0.0001); 75 97 } 76 98 77 99 @Test 78 public void testSelection() { 79 LinearAdditiveUtilitySpace space = mock(LinearAdditiveUtilitySpace.class); 100 public void benchmark() { 101 System.out.println("\nBenchmarking " + profile.getName()); 102 BigInteger domainsize = new AllBidsList(profile.getDomain()).size(); 80 103 81 when(space.getDomain()).thenReturn(domain); 82 when(space.getUtility(any(Bid.class))).thenReturn(ZERO_2); 83 BidsWithUtility selected = new BidsWithUtility(space, new BigDecimal("0.1"), new BigDecimal("0.3")); 84 assertEquals(new BigInteger("6"), selected.size()); 85 } 86 87 @Test 88 public void testRealSpace() throws IOException { 89 String file1 = new String(Files.readAllBytes(Paths.get("src/test/resources/jobs/jobs1.json"))); 90 LinearAdditiveUtilitySpace profile = (LinearAdditiveUtilitySpace) jackson.readValue(file1, Profile.class); 91 BidsWithUtility selected = new BidsWithUtility(profile, ZERO_1, ZERO_3); 92 93 assertEquals(new BigInteger("56"), selected.size()); 94 for (Bid bid : selected) { 95 assertEquals(1, profile.getUtility(bid).compareTo(ZERO_1)); 96 assertEquals(-1, profile.getUtility(bid).compareTo(ZERO_3)); 97 } 104 long start = System.currentTimeMillis(); 105 BidsWithUtility body = new BidsWithUtility(profile, accuracy); 106 ImmutableList<Bid> list = body.getBids(utilityGoal); 107 long end = System.currentTimeMillis(); 108 System.out.println("run time: " + (end - start) / 1000. + "s"); 109 System.out.println("Total size of bidspace:" + domainsize); 110 System.out.println("Result size: " + list.size()); 98 111 } 99 112 -
events/pom.xml
r1 r4 134 134 <target>1.8</target> 135 135 </configuration> 136 </plugin> 137 <plugin> 138 <groupId>org.apache.maven.plugins</groupId> 139 <artifactId>maven-source-plugin</artifactId> 140 <executions> 141 <execution> 142 <id>attach-sources</id> 143 <goals> 144 <goal>jar</goal> 145 </goals> 146 </execution> 147 </executions> 136 148 </plugin> 137 149 -
exampleparties/boulware/pom.xml
r2 r4 74 74 <target>1.8</target> 75 75 </configuration> 76 </plugin> 77 <plugin> 78 <groupId>org.apache.maven.plugins</groupId> 79 <artifactId>maven-source-plugin</artifactId> 80 <executions> 81 <execution> 82 <id>attach-sources</id> 83 <goals> 84 <goal>jar</goal> 85 </goals> 86 </execution> 87 </executions> 76 88 </plugin> 77 89 -
exampleparties/conceder/pom.xml
r2 r4 74 74 <target>1.8</target> 75 75 </configuration> 76 </plugin> 77 <plugin> 78 <groupId>org.apache.maven.plugins</groupId> 79 <artifactId>maven-source-plugin</artifactId> 80 <executions> 81 <execution> 82 <id>attach-sources</id> 83 <goals> 84 <goal>jar</goal> 85 </goals> 86 </execution> 87 </executions> 76 88 </plugin> 77 89 -
exampleparties/hardliner/pom.xml
r2 r4 74 74 <target>1.8</target> 75 75 </configuration> 76 </plugin> 77 <plugin> 78 <groupId>org.apache.maven.plugins</groupId> 79 <artifactId>maven-source-plugin</artifactId> 80 <executions> 81 <execution> 82 <id>attach-sources</id> 83 <goals> 84 <goal>jar</goal> 85 </goals> 86 </execution> 87 </executions> 76 88 </plugin> 77 89 -
exampleparties/linear/pom.xml
r2 r4 74 74 <target>1.8</target> 75 75 </configuration> 76 </plugin> 77 <plugin> 78 <groupId>org.apache.maven.plugins</groupId> 79 <artifactId>maven-source-plugin</artifactId> 80 <executions> 81 <execution> 82 <id>attach-sources</id> 83 <goals> 84 <goal>jar</goal> 85 </goals> 86 </execution> 87 </executions> 76 88 </plugin> 77 89 -
exampleparties/randomparty/pom.xml
r2 r4 156 156 <target>1.8</target> 157 157 </configuration> 158 </plugin> 159 <plugin> 160 <groupId>org.apache.maven.plugins</groupId> 161 <artifactId>maven-source-plugin</artifactId> 162 <executions> 163 <execution> 164 <id>attach-sources</id> 165 <goals> 166 <goal>jar</goal> 167 </goals> 168 </execution> 169 </executions> 158 170 </plugin> 159 171 -
exampleparties/randompartypy/pom.xml
r2 r4 147 147 <target>1.8</target> 148 148 </configuration> 149 </plugin> 150 <plugin> 151 <groupId>org.apache.maven.plugins</groupId> 152 <artifactId>maven-source-plugin</artifactId> 153 <executions> 154 <execution> 155 <id>attach-sources</id> 156 <goals> 157 <goal>jar</goal> 158 </goals> 159 </execution> 160 </executions> 149 161 </plugin> 150 162 -
exampleparties/timedependentparty/pom.xml
r2 r4 158 158 </plugin> 159 159 160 <plugin> 161 <groupId>org.apache.maven.plugins</groupId> 162 <artifactId>maven-source-plugin</artifactId> 163 <executions> 164 <execution> 165 <id>attach-sources</id> 166 <goals> 167 <goal>jar</goal> 168 </goals> 169 </execution> 170 </executions> 171 </plugin> 160 172 161 173 <plugin> -
exampleparties/timedependentparty/src/main/java/geniusweb/exampleparties/timedependentparty/TimeDependentParty.java
r3 r4 3 3 import java.io.IOException; 4 4 import java.math.BigDecimal; 5 import java.math.BigInteger; 5 6 import java.net.URI; 6 7 import java.net.URISyntaxException; … … 14 15 import geniusweb.actions.Offer; 15 16 import geniusweb.actions.PartyId; 16 import geniusweb.bidspace.AllBidsList;17 import geniusweb.bidspace.BidsWithUtility;18 17 import geniusweb.issuevalue.Bid; 19 18 import geniusweb.party.Capabilities; … … 24 23 import geniusweb.party.inform.Settings; 25 24 import geniusweb.party.inform.YourTurn; 25 import geniusweb.profile.Profile; 26 26 import geniusweb.profile.utilityspace.LinearAdditiveUtilitySpace; 27 import geniusweb.profile.utilityspace.UtilitySpace;28 27 import geniusweb.profileconnection.ProfileConnectionFactory; 29 28 import geniusweb.profileconnection.ProfileInterface; … … 31 30 import geniusweb.progress.ProgressRounds; 32 31 import geniusweb.references.ProtocolRef; 32 import tudelft.utilities.immutablelist.ImmutableList; 33 33 import tudelft.utilities.logging.Reporter; 34 34 … … 41 41 public abstract class TimeDependentParty extends DefaultParty { 42 42 43 private static final BigDecimal DEC0001 = new BigDecimal("0.0001"); 44 private static final BigDecimal DEC100 = new BigDecimal("100"); 43 45 private ProfileInterface profileint; 46 private LinearAdditiveUtilitySpace utilspace = null; // last received space 44 47 private PartyId me; 45 48 private Progress progress; 46 private Double minUtil = null, maxUtil = null;47 49 private Bid lastReceivedBid = null; 48 private double tolerance;50 private ExtendedUtilSpace extendedspace; 49 51 50 52 public TimeDependentParty() { … … 77 79 this.me = settings.getID(); 78 80 this.progress = settings.getProgress(); 79 computeMinMax();80 81 } else if (info instanceof ActionDone) { 81 82 Action otheract = ((ActionDone) info).getAction(); … … 117 118 118 119 private void myTurn() throws IOException { 119 Action myAction = null;120 updateUtilSpace(); 120 121 Bid bid = makeBid(); 121 UtilitySpace utilspace = getUtilSpace();122 122 123 if (lastReceivedBid != null && utilspace.getUtility(lastReceivedBid) 124 .compareTo(utilspace.getUtility(bid)) >= 0) { 123 Action myAction; 124 if (bid == null || lastReceivedBid != null 125 && utilspace.getUtility(lastReceivedBid) 126 .compareTo(utilspace.getUtility(bid)) >= 0) { 127 // if bid==null we failed to suggest next bid. 125 128 myAction = new Accept(me, lastReceivedBid); 126 129 } else { 127 myAction = new Offer(me, makeBid());130 myAction = new Offer(me, bid); 128 131 } 129 132 getConnection().send(myAction); … … 131 134 } 132 135 133 private UtilitySpace getUtilSpace() { 134 return (LinearAdditiveUtilitySpace) profileint.getProfile(); 136 private LinearAdditiveUtilitySpace updateUtilSpace() { 137 Profile newutilspace = profileint.getProfile(); 138 if (!newutilspace.equals(utilspace)) { 139 utilspace = (LinearAdditiveUtilitySpace) newutilspace; 140 extendedspace = new ExtendedUtilSpace(utilspace); 141 } 142 return utilspace; 135 143 } 136 144 137 145 /** 138 * Computes the fields minutil and maxUtil if not yet computed. minutil is 139 * the minimum utility of any bid, but at least the utility of the 140 * reservation bid. maxUtil is the maximum util of any bid. 141 * <p> 142 * TODO this is simplistic, very expensive method and may cause us to run 143 * out of time on large domains. 144 * <p> 145 * Can be called only after profileint has been set. 146 * @return next possible bid with current target utility, or null if no such 147 * bid. 146 148 */ 147 private void computeMinMax() {148 if (this.maxUtil != null && this.minUtil != null)149 return;150 this.minUtil = 1d;151 this.maxUtil = 0d;152 UtilitySpace utilspace = getUtilSpace();153 AllBidsList allbidslist = new AllBidsList(154 profileint.getProfile().getDomain());155 for (Bid bid : allbidslist) {156 double util = utilspace.getUtility(bid).doubleValue();157 if (util < minUtil)158 minUtil = util;159 if (util > maxUtil)160 maxUtil = util;161 }162 163 Bid rvbid = utilspace.getReservationBid();164 if (rvbid != null) {165 double rv = utilspace.getUtility(rvbid).doubleValue();166 if (rv > minUtil)167 minUtil = rv;168 }169 tolerance = 100 / allbidslist.size().longValue();170 tolerance = Math.max(tolerance, 0.1);171 }172 173 149 private Bid makeBid() { 174 150 double time = progress.get(System.currentTimeMillis()); 175 double utilityGoal = utilityGoal(time, getE()); 176 BidsWithUtility options = new BidsWithUtility( 177 (LinearAdditiveUtilitySpace) profileint.getProfile(), 178 BigDecimal.valueOf(utilityGoal), 179 BigDecimal.valueOf(utilityGoal + tolerance)); 151 BigDecimal utilityGoal = utilityGoal(time, getE()); 152 ImmutableList<Bid> options = extendedspace.getBids(utilityGoal); 153 if (options.size() == BigInteger.ZERO) 154 return null; 180 155 // pick a random one. 181 156 return options.get(new Random().nextInt(options.size().intValue())); … … 190 165 * @return the utility goal for this time and e value 191 166 */ 192 private double utilityGoal(double t, double e) { 167 private BigDecimal utilityGoal(double t, double e) { 168 BigDecimal minUtil = extendedspace.getMin(); 169 BigDecimal maxUtil = extendedspace.getMax(); 170 193 171 double ft = 0; 194 172 if (e != 0) 195 173 ft = Math.pow(t, 1 / e); 196 // we subtract 0.000001 to correct possibly small round-up errors 197 return minUtil + (maxUtil - minUtil) * (1 - ft) - 0.000001; 174 // we subtract epsilon to correct possibly small round-up errors 175 return new BigDecimal(minUtil.doubleValue() 176 + (maxUtil.doubleValue() - minUtil.doubleValue()) * (1 - ft)) 177 .min(maxUtil).max(minUtil); 198 178 } 199 179 } -
issuevalue/pom.xml
r2 r4 128 128 <target>1.8</target> 129 129 </configuration> 130 </plugin> 131 132 <plugin> 133 <groupId>org.apache.maven.plugins</groupId> 134 <artifactId>maven-source-plugin</artifactId> 135 <executions> 136 <execution> 137 <id>attach-sources</id> 138 <goals> 139 <goal>jar</goal> 140 </goals> 141 </execution> 142 </executions> 130 143 </plugin> 131 144 -
issuevalue/src/main/java/geniusweb/issuevalue/Bid.java
r1 r4 3 3 import java.util.Collections; 4 4 import java.util.HashMap; 5 import java.util.HashSet; 5 6 import java.util.Map; 6 7 import java.util.Set; … … 40 41 41 42 /** 43 * Makes partial bid with just 1 issue and value. 44 * 45 * @param issue the issue name 46 * @param value the {@link Value} 47 */ 48 public Bid(String issue, Value value) { 49 if (issue == null || value == null) { 50 throw new NullPointerException("issue and value must be not =null"); 51 } 52 53 issuevalues = new HashMap<>(); 54 issuevalues.put(issue, value); 55 } 56 57 /** 42 58 * @param issue 43 59 * @return the value for the given issue, or null if there is no value for … … 59 75 public Set<String> getIssues() { 60 76 return Collections.unmodifiableSet(issuevalues.keySet()); 77 } 78 79 /** 80 * Merges this partial bid with another partial bid. 81 * 82 * @param otherbid another partial bid. 83 * @return a bid with the combined values of both partial bids. 84 * @throws IllegalArgumentException if issues overlap. 85 */ 86 public Bid merge(Bid otherbid) { 87 Set<String> ourissues = new HashSet<>(issuevalues.keySet()); 88 ourissues.retainAll(otherbid.getIssues()); 89 if (!ourissues.isEmpty()) { 90 throw new IllegalArgumentException( 91 "Otherbid contains issues that are already set:" 92 + ourissues); 93 } 94 HashMap<String, Value> newvalues = new HashMap<>(issuevalues); 95 newvalues.putAll(otherbid.issuevalues); 96 return new Bid(newvalues); 97 61 98 } 62 99 -
issuevalue/src/test/java/geniusweb/issuevalue/BidTest.java
r1 r4 17 17 import com.fasterxml.jackson.databind.ObjectMapper; 18 18 19 import geniusweb.issuevalue.Bid;20 import geniusweb.issuevalue.DiscreteValue;21 import geniusweb.issuevalue.NumberValue;22 import geniusweb.issuevalue.Value;23 19 import tudelft.utilities.junit.GeneralTests; 24 20 … … 125 121 } 126 122 123 @Test 124 public void testMerge() { 125 Map<String, Value> issuevalues = new HashMap<>(); 126 issuevalues.put(ISSUE1, VALUE1); 127 Bid partial1 = new Bid(issuevalues); 128 129 issuevalues = new HashMap<>(); 130 issuevalues.put(ISSUE2, VALUE2); 131 Bid partial2 = new Bid(issuevalues); 132 133 Bid mergedbid = partial1.merge(partial2); 134 assertEquals(bidc, mergedbid); 135 } 136 137 @Test(expected = IllegalArgumentException.class) 138 public void testMergeIssuesOverlap() { 139 Map<String, Value> issuevalues = new HashMap<>(); 140 issuevalues.put(ISSUE1, VALUE1); 141 Bid partial1 = new Bid(issuevalues); 142 143 issuevalues = new HashMap<>(); 144 issuevalues.put(ISSUE1, VALUE2); 145 Bid partial2 = new Bid(issuevalues); 146 147 partial1.merge(partial2); 148 } 149 150 @Test 151 public void smokeTestConstructor2() { 152 new Bid("issue", new DiscreteValue("dss")); 153 } 154 155 @Test 156 public void smokeTestConstructor2b() { 157 new Bid("issue", new NumberValue("0.5")); 158 } 159 160 @Test(expected = NullPointerException.class) 161 public void smokeTestConstructor2Null1() { 162 new Bid(null, new DiscreteValue("dss")); 163 } 164 165 @Test(expected = NullPointerException.class) 166 public void smokeTestConstructor2Null2() { 167 new Bid("issue", null); 168 } 169 127 170 } -
party/pom.xml
r1 r4 154 154 <target>1.8</target> 155 155 </configuration> 156 </plugin> 157 <plugin> 158 <groupId>org.apache.maven.plugins</groupId> 159 <artifactId>maven-source-plugin</artifactId> 160 <executions> 161 <execution> 162 <id>attach-sources</id> 163 <goals> 164 <goal>jar</goal> 165 </goals> 166 </execution> 167 </executions> 156 168 </plugin> 157 169 -
profile/pom.xml
r1 r4 134 134 <target>1.8</target> 135 135 </configuration> 136 </plugin> 137 <plugin> 138 <groupId>org.apache.maven.plugins</groupId> 139 <artifactId>maven-source-plugin</artifactId> 140 <executions> 141 <execution> 142 <id>attach-sources</id> 143 <goals> 144 <goal>jar</goal> 145 </goals> 146 </execution> 147 </executions> 136 148 </plugin> 137 149 -
profile/src/main/java/geniusweb/profile/utilityspace/LinearAdditiveUtilitySpace.java
r1 r4 8 8 import com.fasterxml.jackson.annotation.JsonAutoDetect; 9 9 import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; 10 import com.fasterxml.jackson.annotation.JsonCreator; 11 import com.fasterxml.jackson.annotation.JsonProperty; 10 12 11 13 import geniusweb.issuevalue.Bid; 12 14 import geniusweb.issuevalue.Domain; 13 15 import geniusweb.issuevalue.Value; 14 15 import com.fasterxml.jackson.annotation.JsonCreator;16 import com.fasterxml.jackson.annotation.JsonProperty;17 16 18 17 /** … … 221 220 222 221 /** 223 * @return the map from issue names to valuesetutilities 222 * @return the map from issue names to valuesetutilities (un-weighted) 224 223 */ 225 224 public Map<String, ValueSetUtilities> getUtilities() { -
profile/src/main/java/geniusweb/profile/utilityspace/NumberValueSetUtilities.java
r3 r4 106 106 } 107 107 108 /** 109 * @return the lowest value 110 */ 111 public BigDecimal getLowValue() { 112 return lowValue; 113 } 114 115 /** 116 * 117 * @return the highest value 118 */ 119 public BigDecimal getHighValue() { 120 return highValue; 121 } 122 123 /** 124 * 125 * @return the utility of the lowest value 126 */ 127 public BigDecimal getLowUtility() { 128 return lowUtility; 129 } 130 131 /** 132 * 133 * @return the utility of the highest value 134 */ 135 public BigDecimal getHighUtility() { 136 return highUtility; 137 } 138 108 139 @Override 109 140 public String toString() { -
profileconnection/pom.xml
r1 r4 143 143 <target>1.8</target> 144 144 </configuration> 145 </plugin> 146 <plugin> 147 <groupId>org.apache.maven.plugins</groupId> 148 <artifactId>maven-source-plugin</artifactId> 149 <executions> 150 <execution> 151 <id>attach-sources</id> 152 <goals> 153 <goal>jar</goal> 154 </goals> 155 </execution> 156 </executions> 145 157 </plugin> 146 158 -
protocol/src/main/java/geniusweb/protocol/ProtocolException.java
r1 r4 13 13 14 14 /** 15 *16 15 * @param message the error message 17 16 * @param party offending party, either the {@link PartyId} or a … … 19 18 */ 20 19 public ProtocolException(String message, String party) { 21 super(party + ":" + message); 22 this.party = party; 20 this(message, party, null); 23 21 } 24 22 25 23 /** 24 * ProtocolException is special, in that it does not auto-fill the 25 * stacktrace. This is needed because usually a ProtocolException is caused 26 * by a party doing a bad action. Creating a stacktrace pointing to the 27 * class reporting the protocol exception (usually, the protocol handler) 28 * makes no sense as the protocol handler is doing the correct job there. 29 * 26 30 * 27 31 * @param message the error message … … 31 35 */ 32 36 public ProtocolException(String message, String party, Throwable e) { 33 super(party + ":" + message, e );37 super(party + ":" + message, e, true, false); 34 38 this.party = party; 35 39 } -
protocol/src/main/java/geniusweb/protocol/session/saop/SAOP.java
r1 r4 2 2 3 3 import java.io.IOException; 4 import java.sql.Date; 5 import java.text.SimpleDateFormat; 4 6 import java.util.List; 5 7 import java.util.Timer; … … 190 192 "BUG. Deadline timer has triggered but state is not final"); 191 193 } 194 log.log(Level.WARNING, 195 "SAOP deadline reached. Terminating session."); 192 196 finish(); 193 197 } … … 196 200 // early 197 201 deadlinetimer.schedule(task, deadline.getDuration() + TIME_MARGIN); 202 log.log(Level.INFO, "SAOP deadline set to " 203 + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss") 204 .format(new Date(System.currentTimeMillis() 205 + deadline.getDuration() + TIME_MARGIN))); 198 206 } 199 207 … … 251 259 final ConnectionWithParty partyconn, final Action action) { 252 260 if (action == null) { 253 handleError("Received null from " + partyconn + ". Closing session", 261 handleError(partyconn 262 + " did null action, breaching the protocol. Closing session", 254 263 partyconn.getParty().getName(), null); 255 264 return; … … 259 268 if (!partyconn.getParty().equals(state.getNextActor())) { 260 269 // party does not have the turn. 261 throw new ProtocolException(" act without having the turn", 270 throw new ProtocolException( 271 "Party acts without having the turn", 262 272 partyconn.getParty().getName()); 263 273 } -
protocol/src/main/java/geniusweb/protocol/session/saop/SAOPState.java
r1 r4 189 189 } 190 190 if (!actor.equals(getNextActor())) { 191 throw new ProtocolException(" actordoes not have the turn ",191 throw new ProtocolException("Party does not have the turn ", 192 192 actor.getName()); 193 193 … … 211 211 if (!bid.equals(((Accept) action).getBid())) { 212 212 throw new ProtocolException( 213 " Accepts a bid that was not offered (last offer =" + bid214 + ", action=" + action + ")",213 "Party accepts a bid differing from the last offer =" 214 + bid + ", action=" + action + ")", 215 215 actor.getName()); 216 216 } -
protocol/src/test/java/geniusweb/protocol/session/saop/SAOPStateTest.java
r1 r4 284 284 assertTrue(state.isFinal(NOW)); 285 285 assertEquals( 286 "geniusweb.protocol.ProtocolException: party1: actordoes not have the turn ",286 "geniusweb.protocol.ProtocolException: party1:Party does not have the turn ", 287 287 state.getError().toString()); 288 288 } … … 297 297 state = state.with(party2, nullaccept); 298 298 assertTrue(state.isFinal(NOW)); 299 assertTrue(state.getError().toString() 300 .matches(".*party2.*Accepts a bid that was not offered.*"));299 assertTrue(state.getError().toString().matches( 300 ".*party2.*Party accepts a bid differing from the last offer.*")); 301 301 } 302 302 -
timeline/pom.xml
r1 r4 121 121 <target>1.8</target> 122 122 </configuration> 123 </plugin> 124 <plugin> 125 <groupId>org.apache.maven.plugins</groupId> 126 <artifactId>maven-source-plugin</artifactId> 127 <executions> 128 <execution> 129 <id>attach-sources</id> 130 <goals> 131 <goal>jar</goal> 132 </goals> 133 </execution> 134 </executions> 123 135 </plugin> 124 136
Note:
See TracChangeset
for help on using the changeset viewer.