source: geniuswebcore/test/geniusweb/profile/utilityspace/LinearAdditiveTest.py@ 60

Last change on this file since 60 was 59, checked in by Wouter Pasman, 3 years ago

#44 manual commit of first public release, because this will cause the dist directory to move

File size: 8.7 KB
Line 
1from decimal import Decimal
2import json
3from pathlib import Path
4from typing import Dict
5import unittest
6
7from pyson.ObjectMapper import ObjectMapper
8
9from geniusweb.issuevalue.Bid import Bid
10from geniusweb.issuevalue.DiscreteValue import DiscreteValue
11from geniusweb.issuevalue.DiscreteValueSet import DiscreteValueSet
12from geniusweb.issuevalue.Domain import Domain
13from geniusweb.issuevalue.NumberValue import NumberValue
14from geniusweb.issuevalue.ValueSet import ValueSet
15from geniusweb.profile.Profile import Profile
16from geniusweb.profile.utilityspace.DiscreteValueSetUtilities import DiscreteValueSetUtilities
17from geniusweb.profile.utilityspace.LinearAdditiveUtilitySpace import LinearAdditiveUtilitySpace
18from geniusweb.profile.utilityspace.ValueSetUtilities import ValueSetUtilities
19
20
21class LinearAdditiveTest(unittest.TestCase):
22 pyson=ObjectMapper()
23
24 yesno = DiscreteValueSet([DiscreteValue("yes"), DiscreteValue("no")])
25 leasecarvals = yesno
26 permcontractvals = yesno
27 carreervals=DiscreteValueSet([DiscreteValue("low"),DiscreteValue("medium"),DiscreteValue("high")])
28 ftevals=DiscreteValueSet([DiscreteValue("0.6"),DiscreteValue("0.8"),DiscreteValue("1.0")])
29 salaryvals=DiscreteValueSet([DiscreteValue("2000"),DiscreteValue("2500"),
30 DiscreteValue("3000"),DiscreteValue("3500"),DiscreteValue("4000")])
31 workfromhomevals=DiscreteValueSet([DiscreteValue("0"),DiscreteValue("1"),DiscreteValue("2")])
32
33 jobsdomain = Domain("jobs", {"lease car":leasecarvals, "permanent contract":permcontractvals, \
34 "career development opportunities":carreervals, "fte":ftevals, \
35 "salary": salaryvals, "work from home": workfromhomevals })
36 N0=Decimal("0")
37 N1=Decimal("1")
38 N025=Decimal("0.25")
39 N03=Decimal("0.3")
40 N05=Decimal("0.5")
41 N075=Decimal("0.75")
42
43 leasevarutils = DiscreteValueSetUtilities({DiscreteValue("no"):N0, DiscreteValue("yes"):N1})
44 leasevarutils2 = DiscreteValueSetUtilities({DiscreteValue("no"):N0, DiscreteValue("yes"):N075})
45 permcontrutils = DiscreteValueSetUtilities({DiscreteValue("no"):N0, DiscreteValue("yes"):N1})
46 carreerutils = DiscreteValueSetUtilities({DiscreteValue("high"):N1,DiscreteValue("low"):N0,DiscreteValue("medium"):N05})
47 fteutils = DiscreteValueSetUtilities({DiscreteValue("1.0"):N075,DiscreteValue("0.6"):N025,DiscreteValue("0.8"):N05})
48 salaryutils = DiscreteValueSetUtilities({DiscreteValue("4000"):N1,DiscreteValue("2500"):N025,DiscreteValue("3500"):N075,
49 DiscreteValue("2000"):N0,DiscreteValue("3000"):N03})
50 fromhomeutils = DiscreteValueSetUtilities({DiscreteValue("1"):N05,DiscreteValue("2"):Decimal("0.666666666666"),
51 DiscreteValue("0"):Decimal("0.333333333")})
52 utils:Dict[str, ValueSetUtilities] = {'lease car': leasevarutils, 'permanent contract':permcontrutils, 'career development opportunities': carreerutils,
53 'fte':fteutils, 'salary':salaryutils, 'work from home':fromhomeutils }
54 utils2:Dict[str, ValueSetUtilities] = {'lease car': leasevarutils2, 'permanent contract':permcontrutils, 'career development opportunities': carreerutils,
55 'fte':fteutils, 'salary':salaryutils, 'work from home':fromhomeutils }
56 weights:Dict[str, Decimal] = {"lease car":Decimal("0.06"),"permanent contract":Decimal("0.16"),
57 "career development opportunities":Decimal("0.04"),"fte":Decimal("0.32"),
58 "salary":Decimal("0.24"),"work from home":Decimal("0.18")}
59 weights2:Dict[str, Decimal] = {"lease car":Decimal("0.06"),"permanent contract":Decimal("0.16"),
60 "career development opportunities":Decimal("0.05"),"fte":Decimal("0.31"),
61 "salary":Decimal("0.24"),"work from home":Decimal("0.18")}
62
63 jobs=LinearAdditiveUtilitySpace(jobsdomain, "jobs1",utils, weights )
64 jobs1=LinearAdditiveUtilitySpace(jobsdomain, "jobs1",utils, weights )
65 jobs2=LinearAdditiveUtilitySpace(jobsdomain, "jobs2",utils, weights )
66 jobs3=LinearAdditiveUtilitySpace(jobsdomain, "jobs",utils2, weights )
67 jobs4=LinearAdditiveUtilitySpace(jobsdomain, "jobs",utils, weights2 )
68
69 # A real jobs profile from profiles server
70 # "reservationBid":null was added because toJson will also add this (even though it's the default value)
71 jobsstr = '{"LinearAdditiveUtilitySpace":{"issueUtilities":{' \
72 + '"lease car":{"DiscreteValueSetUtilities":{"valueUtilities":{"no":0,"yes":1}}},' \
73 + '"permanent contract":{"DiscreteValueSetUtilities":{"valueUtilities":{"no":0,"yes":1}}},' \
74 + '"career development opportunities":{"DiscreteValueSetUtilities":{"valueUtilities":{"high":1,"low":0,"medium":0.5}}},' \
75 + '"fte":{"DiscreteValueSetUtilities":{"valueUtilities":{"1.0":0.75,"0.6":0.25,"0.8":0.5}}},' \
76 + '"salary":{"DiscreteValueSetUtilities":{"valueUtilities":{"4000":1,"2500":0.25,"3500":0.75,"2000":0,"3000":0.3}}},' \
77 + '"work from home":{"DiscreteValueSetUtilities":{"valueUtilities":{"1":0.5,"2":0.666666666666,"0":0.333333333}}}},' \
78 + '"issueWeights":{"lease car":0.06,"permanent contract":0.16,' \
79 + '"career development opportunities":0.04,"fte":0.32,"salary":0.24,"work from home":0.18},' \
80 + '"domain":{"name":"jobs","issuesValues":{"lease car":{"values":["yes","no"]},"permanent contract":{"values":["yes","no"]},"career development opportunities":{"values":["low","medium","high"]},"fte":{"values":["0.6","0.8","1.0"]},"salary":{"values":["2000","2500","3000","3500","4000"]},"work from home":{"values":["0","1","2"]}}},'\
81 + '"name":"jobs1", "reservationBid":null}}'
82
83 jobsjson = json.loads(jobsstr)
84
85 partystr='{"LinearAdditiveUtilitySpace":{"domain":{"name":"party","issuesValues":{"Invitations":{"values":["Plain","Photo","Custom, Handmade","Custom, Printed"]},"Music":{"values":["MP3","DJ","Band"]},"Drinks":{"values":["Non-Alcoholic","Beer Only","Handmade Cocktails","Catering"]},"Cleanup":{"values":["Water and Soap","Specialized Materials","Special Equiment","Hired Help"]},"Food":{"values":["Chips and Nuts","Finger-Food","Handmade Food","Catering"]},"Location":{"values":["Party Tent","Your Dorm","Party Room","Ballroom"]}}},"name":"party1","issueUtilities":{"Invitations":{"DiscreteValueSetUtilities":{"valueUtilities":{"Plain":0.24,"Custom, Printed":0.48,"Photo":0.74,"Custom, Handmade":1}}},"Music":{"DiscreteValueSetUtilities":{"valueUtilities":{"DJ":0.99,"Band":0.35,"MP3":0.65}}},"Drinks":{"DiscreteValueSetUtilities":{"valueUtilities":{"Handmade Cocktails":0.672,"Non-Alcoholic":0.263,"Beer Only":0.98,"Catering":0.334}}},"Cleanup":{"DiscreteValueSetUtilities":{"valueUtilities":{"Special Equiment":0.32,"Water and Soap":0.65,"Specialized Materials":0.96,"Hired Help":0.31}}},"Food":{"DiscreteValueSetUtilities":{"valueUtilities":{"Finger-Food":0.52,"Handmade Food":0.51,"Catering":0.25,"Chips and Nuts":0.75}}},"Location":{"DiscreteValueSetUtilities":{"valueUtilities":{"Your Dorm":0.23,"Ballroom":0.77,"Party Room":0.99,"Party Tent":0.52}}}},"issueWeights":{"Invitations":0.05,"Music":0.19,"Drinks":0.28,"Cleanup":0.10,"Food":0.19,"Location":0.19},"reservationBid":null}}'
86 partyjson = json.loads(partystr)
87
88 def testSerialize(self):
89 print(self.pyson.toJson(self.jobs))
90 self.maxDiff=None
91 self.assertEqual(self.jobsjson, self.pyson.toJson(self.jobs))
92
93 def testDeserialize(self):
94 self.assertEqual(self.jobs, self.pyson.parse(self.jobsjson, Profile))
95
96 def testDeserializeJapanTrip(self):
97 serialized = Path("test/resources/japantrip1.json").read_text("utf-8")
98 jsonobj=json.loads(serialized)
99 profile:Profile = self.pyson.parse(jsonobj, Profile);
100 self.assertEquals("japantrip1", profile.getName())
101 self.assertEquals("japantrip", profile.getDomain().getName())
102
103 def testDeserializeParty1(self):
104 print( str(self.pyson.parse(self.partyjson, Profile)))
105
106 def testEquals(self):
107 self.assertEqual(self.jobs,self.jobs1)
108 self.assertEqual(hash(self.jobs),hash(self.jobs1))
109 self.assertNotEqual(self.jobs,self.jobs2)
110 self.assertNotEqual(hash(self.jobs),hash(self.jobs2))
111 self.assertNotEqual(self.jobs,self.jobs3)
112 self.assertNotEqual(hash(self.jobs),hash(self.jobs3))
113 self.assertNotEqual(self.jobs,self.jobs4)
114 self.assertNotEqual(hash(self.jobs),hash(self.jobs4))
115
116
117 def testUtil(self):
118 bid=Bid({"lease car":DiscreteValue("yes"), "permanent contract":DiscreteValue("yes"), \
119 "career development opportunities": DiscreteValue("low"), \
120 "fte": DiscreteValue("0.8"), "salary":DiscreteValue("2500"), "work from home": DiscreteValue("1") });
121 # 0.06 * 1 + 0.16 * 1 + 0.04 * 0 + 0.32 * 0.5 + 0.24 * 0.25 + 0.18 * 0.5
122 self.assertEqual(Decimal("0.53"), self.jobs.getUtility(bid))
Note: See TracBrowser for help on using the repository browser.