source: bidspace/src/main/java/geniusweb/bidspace/pareto/PartialPareto.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.2 KB
Line 
1package geniusweb.bidspace.pareto;
2
3import java.util.HashMap;
4import java.util.LinkedList;
5import java.util.List;
6import java.util.Map;
7
8import geniusweb.issuevalue.Bid;
9import geniusweb.issuevalue.Value;
10import geniusweb.profile.utilityspace.LinearAdditive;
11
12/**
13 * PartialPareto contains a pareto surface of partial bids. Internal-only
14 * utility class for computing LinearAdditive pareto surface. Immutable.
15 */
16class PartialPareto {
17 private final List<ParetoPoint> points;
18
19 /**
20 * @param points the points to be contained in this PartialPareto
21 */
22 private PartialPareto(List<ParetoPoint> points) {
23 this.points = points;
24 }
25
26 /**
27 * Constructor. Avoided the standard 'new' constructor as this is
28 * implemented recursively (O(log(#issues))).
29 *
30 * @param utilSpaces the {@link LinearAdditive}s
31 * @param issues the issues (subset of all issues in the space) to be
32 * used for this pareto
33 * @return the pareto surface (non-dominated bids) when considering only the
34 * given issues.
35 */
36 public static PartialPareto create(List<LinearAdditive> utilSpaces,
37 List<String> issues) {
38
39 if (issues.size() == 1) {
40 String issue = issues.get(0);
41 Map<String, Value> map = new HashMap<>();
42 List<ParetoPoint> list = new LinkedList<>();
43 for (Value value : utilSpaces.get(0).getDomain().getValues(issue)) {
44 map.put(issue, value);
45 list = add(list, new ParetoPoint(new Bid(map), utilSpaces));
46 }
47 return new PartialPareto(list);
48 } else {
49 int halfway = issues.size() / 2;
50 return create(utilSpaces, issues.subList(0, halfway)).merge(
51 create(utilSpaces, issues.subList(halfway, issues.size())));
52 }
53 }
54
55 /**
56 *
57 * @return the ParetoPoints on the (possibly partial) Pareto surface
58 */
59 public List<ParetoPoint> getPoints() {
60 return points;
61 }
62
63 /**
64 * This combines two partial paretos. Here is the heart of the algorithm.
65 *
66 * @param other another {@link PartialPareto} to be merged with this. The
67 * other pareto must be composed with non-overlapping range.
68 * @return merge of two partial paretos. Checks all partial1*partial2
69 * combinations and only non-dominated points are kept.
70 */
71 private PartialPareto merge(PartialPareto other) {
72 List<ParetoPoint> merge = new LinkedList<>();// fast add and iterate
73 for (ParetoPoint point : points) {
74 for (ParetoPoint otherpoint : other.points) {
75 merge = add(merge, point.merge(otherpoint));
76 }
77 }
78 return new PartialPareto(merge);
79 }
80
81 /**
82 * Add a new ParetoPoint to a list
83 *
84 * @param list the existing list
85 * @param candidate a new {@link ParetoPoint} candidate
86 * @return a new list that either ignored the candidate, or added it and
87 * removed the old points that are dominated by the candidate
88 */
89 private static List<ParetoPoint> add(List<ParetoPoint> list,
90 ParetoPoint candidate) {
91 for (ParetoPoint existing : list) {
92 if (candidate.isDominatedBy(existing)) {
93 return list;
94 }
95 }
96 // if we get here, candidate is not dominated so we add it
97 // and remove existing ones now dominated
98 List<ParetoPoint> newlist = new LinkedList<ParetoPoint>();
99 newlist.add(candidate);
100 for (ParetoPoint existing : list) {
101 if (!existing.isDominatedBy(candidate)) {
102 newlist.add(existing);
103 }
104 }
105 return newlist;
106 }
107
108}
Note: See TracBrowser for help on using the repository browser.