source: java2python/geniuswebtranslator/geniuswebsrc/geniusweb/bidspace/pareto/GenericPareto.java@ 837

Last change on this file since 837 was 825, checked in by wouter, 6 months ago

#291 move annotation to above the javadoc

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