1 | from decimal import Decimal
|
---|
2 | from typing import Set, Dict
|
---|
3 | import unittest
|
---|
4 | from unittest.mock import Mock
|
---|
5 |
|
---|
6 | from geniusweb.bidspace.pareto.PartialPareto import PartialPareto
|
---|
7 | from geniusweb.issuevalue.Bid import Bid
|
---|
8 | from geniusweb.issuevalue.DiscreteValueSet import DiscreteValueSet
|
---|
9 | from geniusweb.issuevalue.Domain import Domain
|
---|
10 | from geniusweb.issuevalue.NumberValue import NumberValue
|
---|
11 | from geniusweb.issuevalue.NumberValueSet import NumberValueSet
|
---|
12 | from geniusweb.issuevalue.Value import Value
|
---|
13 | from geniusweb.issuevalue.ValueSet import ValueSet
|
---|
14 | from geniusweb.profile.utilityspace.LinearAdditive import LinearAdditive
|
---|
15 |
|
---|
16 |
|
---|
17 | class PartialParetoTest(unittest.TestCase):
|
---|
18 | D0_0 = Decimal(0)
|
---|
19 | D0_2 = Decimal("0.2")
|
---|
20 | D0_1 = Decimal("0.1")
|
---|
21 | D0_3 = Decimal("0.3")
|
---|
22 | D0_4 = Decimal("0.4")
|
---|
23 | D0_5 = Decimal("0.5")
|
---|
24 |
|
---|
25 | space1 = Mock(LinearAdditive)
|
---|
26 | space2 = Mock(LinearAdditive)
|
---|
27 |
|
---|
28 | domain = Mock(Domain)
|
---|
29 | issues:Set[str] = set(["issue1", "issue2"])
|
---|
30 | value1a = Mock(Value)
|
---|
31 | value1b = Mock(Value)
|
---|
32 | value2a = Mock(Value)
|
---|
33 | value2b = Mock(Value)
|
---|
34 |
|
---|
35 | def setUp(self):
|
---|
36 |
|
---|
37 | map:Dict[str, Value] = {}
|
---|
38 | map["issue1"] = self.value1a
|
---|
39 | self.bid10 = Bid(map)
|
---|
40 | map["issue1"] = self.value1b
|
---|
41 | self.bid20 = Bid(map)
|
---|
42 |
|
---|
43 | map = {}
|
---|
44 | map["issue2"] = self.value2a
|
---|
45 | self.bid01 = Bid(map)
|
---|
46 | map["issue2"] = self.value2b
|
---|
47 | self.bid02 = Bid(map)
|
---|
48 |
|
---|
49 | self.space1.getUtility = Mock(side_effect=lambda b: \
|
---|
50 | {self.bid10:self.D0_1, self.bid20:self.D0_2, \
|
---|
51 | self.bid01:self.D0_0, self.bid02:self.D0_0 }[b])
|
---|
52 | self.space2.getUtility = Mock(side_effect=lambda b: \
|
---|
53 | {self.bid10:self.D0_0, self.bid20:self.D0_0, \
|
---|
54 | self.bid01:self.D0_0, self.bid02:self.D0_2 }[b])
|
---|
55 |
|
---|
56 | self.space1.getDomain = Mock(return_value=self.domain)
|
---|
57 | self.domain.getIssues = Mock(return_value=self.issues)
|
---|
58 | self.issue1valueset = DiscreteValueSet([self.value1a, self.value1b])
|
---|
59 | self.domain.getValues = Mock(side_effect=lambda iss:\
|
---|
60 | {"issue1":self.issue1valueset, "issue2":self.issue2valueset}[iss])
|
---|
61 |
|
---|
62 | # by putting the best value first in the list now,
|
---|
63 | # we may trigger a different evaluation path in the PartialPareto
|
---|
64 | # algorithm, improving coverage
|
---|
65 | self.issue2valueset = DiscreteValueSet([self.value2b, self.value2a])
|
---|
66 |
|
---|
67 | def testOneIssueTest(self):
|
---|
68 | pp = PartialPareto.create([self.space1, self.space2], ["issue1"])
|
---|
69 | # bid22 is best for both. Check that's the only remaining point
|
---|
70 | self.assertEqual(1, len(pp.getPoints()))
|
---|
71 | map:Dict[str, Value] = {}
|
---|
72 | map["issue1"] = self.value1b
|
---|
73 | # there is no value for issue2 because we asked to exclude it from the
|
---|
74 | # pareto.
|
---|
75 | self.assertEqual(Bid(map), pp.getPoints()[0].getBid())
|
---|
76 |
|
---|
77 | def testTwoIssuesTest(self):
|
---|
78 | pp = PartialPareto.create([self.space1, self.space2],
|
---|
79 | ["issue1", "issue2"])
|
---|
80 | # bid22 is best for both. Check that's the only remaining point
|
---|
81 | self.assertEqual(1, len(pp.getPoints()))
|
---|
82 | map:Dict[str, Value] = {}
|
---|
83 | map["issue1"] = self.value1b
|
---|
84 | map["issue2"] = self.value2b
|
---|
85 | self.assertEqual(Bid(map), pp.getPoints()[0].getBid())
|
---|