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