source: bidspace/src/main/java/geniusweb/bidspace/pareto/GenericPareto.java@ 31

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

New protocols Learn and APPLearn. Fixed memory leak.

File size: 3.1 KB
Line 
1package geniusweb.bidspace.pareto;
2
3import java.util.HashSet;
4import java.util.List;
5import java.util.Set;
6import java.util.stream.Collectors;
7
8import geniusweb.bidspace.AllBidsList;
9import geniusweb.issuevalue.Bid;
10import geniusweb.issuevalue.Domain;
11import geniusweb.profile.PartialOrdering;
12import geniusweb.profile.Profile;
13
14/**
15 * A set of all pareto points associated with a set of profiles. Generally
16 * applicable but slow.
17 */
18public class GenericPareto implements ParetoFrontier {
19
20 private final List<? extends PartialOrdering> profiles;
21 private Set<Bid> paretobids = null;
22
23 /**
24 * Constructs pareto from a general {@link PartialOrdering}. This is a
25 * brute-force algorithm that will inspect (but not store) ALL bids in the
26 * space, and therefore may be inapproproate depending on the size of your
27 * domain. Complexity O( |bidspace|^2 |profiles| )
28 *
29 * @param profiles a set of at least 2 {@link PartialOrdering}s. All must be
30 * defined on the same domain.
31 */
32 public GenericPareto(List<? extends PartialOrdering> profiles) {
33 if (profiles.size() < 2) {
34 throw new IllegalArgumentException(
35 "at least 2 profiles are needed");
36 }
37 if (profiles.stream().anyMatch(profile -> profile == null)) {
38 throw new IllegalArgumentException("Profiles must not be null");
39 }
40 Domain domain = profiles.get(0).getDomain();
41 for (PartialOrdering profile : profiles) {
42 if (!domain.equals(profile.getDomain())) {
43 throw new IllegalArgumentException(
44 "All profiles must be on same domain ("
45 + domain.getName() + ") but found " + profile);
46 }
47 }
48 this.profiles = profiles;
49 }
50
51 @Override
52 public List<? extends Profile> getProfiles() {
53 return profiles;
54 }
55
56 @Override
57 public synchronized Set<Bid> getPoints() {
58 if (paretobids == null)
59 computePareto();
60 return paretobids;
61 }
62
63 @Override
64 public String toString() {
65 return "Pareto " + getPoints();
66 }
67
68 /**
69 * assigns {@link #paretobids}.
70 */
71 private void computePareto() {
72 paretobids = new HashSet<Bid>();
73
74 for (Bid newbid : new AllBidsList(profiles.get(0).getDomain())) {
75 /*
76 * invariant: paretobids contains bids not dominated by other bids
77 * in paretobids. That means we need (1) check if new bid is
78 * dominated (2) if existing bids are dominated if we add a new bid
79 */
80 boolean newBidIsDominated = paretobids.stream()
81 .anyMatch(paretobid -> isDominatedBy(newbid, paretobid));
82
83 // if new bid is not dominated, we add it and we re-check existing
84 // if they are now dominated
85 if (!newBidIsDominated) {
86 paretobids = paretobids.stream()
87 .filter(paretobid -> !isDominatedBy(paretobid, newbid))
88 .collect(Collectors.toSet());
89 paretobids.add(newbid);
90 }
91 }
92 }
93
94 /**
95 *
96 * @param bid1 the bid to check
97 * @param dominantbid the bid that is supposed to dominate bid1
98 * @return true iff bid1 is dominated by dominant bid. "Dominated by" means
99 * that the bid is preferred or equal in all profiles.
100 */
101 private boolean isDominatedBy(Bid bid1, Bid dominantbid) {
102 return profiles.stream().allMatch(
103 profile -> profile.isPreferredOrEqual(dominantbid, bid1));
104 }
105}
Note: See TracBrowser for help on using the repository browser.