1 | import unittest
|
---|
2 | from pyson.ObjectMapper import ObjectMapper
|
---|
3 | from geniusweb.bidspace.Interval import Interval
|
---|
4 | from decimal import Decimal
|
---|
5 | from geniusweb.profile.utilityspace.LinearAdditiveUtilitySpace import LinearAdditiveUtilitySpace
|
---|
6 | import json
|
---|
7 | from geniusweb.profile.Profile import Profile
|
---|
8 | from geniusweb.bidspace.BidsWithUtility import BidsWithUtility
|
---|
9 | from random import randrange
|
---|
10 | from geniusweb.bidspace.AllBidsList import AllBidsList
|
---|
11 | import time
|
---|
12 | from pathlib import Path
|
---|
13 |
|
---|
14 | class BidsWithUtilityTest(unittest.TestCase):
|
---|
15 | jackson = ObjectMapper()
|
---|
16 | utilityGoal = Interval(Decimal("0.50"), Decimal("0.51"))
|
---|
17 | accuracy = 5
|
---|
18 |
|
---|
19 |
|
---|
20 | parameters=[
|
---|
21 | [ "test/resources/jobs/jobs1.json", 11 ],
|
---|
22 | [ "test/resources/7issues/7issues1.json", 260000 ],
|
---|
23 | [ "test/resources/9issues/9issues1.json", 25000000 ]
|
---|
24 | ]
|
---|
25 |
|
---|
26 | def testAll(self):
|
---|
27 | '''
|
---|
28 | runs all the tests. Python has no standard 'parameterized' mechanism
|
---|
29 | so we have to do it ourselves.
|
---|
30 | '''
|
---|
31 | for [filename, expectedsize] in self.parameters:
|
---|
32 | self.filename=filename
|
---|
33 | self.expectedSize= expectedsize
|
---|
34 | with self.subTest("test"+self.filename):
|
---|
35 | self.before()
|
---|
36 | self.simple()
|
---|
37 | with self.subTest("testMaxUtil"+self.filename):
|
---|
38 | self.before()
|
---|
39 | self.MaxUtil()
|
---|
40 | with self.subTest("benchmark"+self.filename):
|
---|
41 | self.before()
|
---|
42 | self.benchmark()
|
---|
43 |
|
---|
44 | def before(self):
|
---|
45 | print("Running from file " + self.filename)
|
---|
46 | file = Path(self.filename).read_text("utf-8")
|
---|
47 | self.profile = self.jackson.parse(json.loads(file), Profile)
|
---|
48 |
|
---|
49 |
|
---|
50 |
|
---|
51 | def simple(self):
|
---|
52 | '''
|
---|
53 | Test if the values are within acceptable range from the goal.
|
---|
54 | '''
|
---|
55 | list = BidsWithUtility.create(self.profile, self.accuracy).getBids(self.utilityGoal);
|
---|
56 | #check not all but only 10000 random bids as list may be way too large
|
---|
57 | #to test them all. Testing 1 billion bids may take 15 minutes or so on
|
---|
58 | #quad core i7 @2.4GHz.....
|
---|
59 | #also notice that we may be checking only part of the list if
|
---|
60 | #the size of the list would become bigger than maxint.
|
---|
61 | for n in range(10000):
|
---|
62 | bid = list.get(randrange(list.size()))
|
---|
63 | self.assertTrue(self.utilityGoal.contains(
|
---|
64 | round(self.profile.getUtility(bid),self.accuracy-1)),
|
---|
65 | "bid "+str(bid)+" is not in range "+str(self.utilityGoal))
|
---|
66 |
|
---|
67 | self.assertTrue(list.size()>= self.expectedSize)
|
---|
68 |
|
---|
69 | def MaxUtil(self) :
|
---|
70 | bidswithutil = BidsWithUtility.create(self.profile)
|
---|
71 | #notice, this is the *rounded* max util
|
---|
72 | maxutil = bidswithutil.getRange().getMax()
|
---|
73 | goal = Interval(maxutil - Decimal("0.00001"), maxutil)
|
---|
74 |
|
---|
75 | bidsnearmax = bidswithutil.getBids(goal)
|
---|
76 | self.assertTrue(bidsnearmax.size() != 0)
|
---|
77 |
|
---|
78 | foundmax = Decimal(0)
|
---|
79 | for bid in bidsnearmax :
|
---|
80 | util = self.profile.getUtility(bid)
|
---|
81 | if util>foundmax:
|
---|
82 | foundmax = util;
|
---|
83 | #found maximum may be slightly lower or higher because we rounded
|
---|
84 | #all weighted utilities.
|
---|
85 | self.assertTrue(abs(foundmax - maxutil) < 0.0001)
|
---|
86 |
|
---|
87 | def benchmark(self):
|
---|
88 | print("\nBenchmarking " + self.profile.getName());
|
---|
89 | domainsize = AllBidsList(self.profile.getDomain()).size()
|
---|
90 |
|
---|
91 | start = round(time.time()*1000)
|
---|
92 | body = BidsWithUtility.create(self.profile, self.accuracy)
|
---|
93 | list = body.getBids(self.utilityGoal)
|
---|
94 | end = round(time.time()*1000)
|
---|
95 | print("run time: " + str((end - start) / 1000.) + "s");
|
---|
96 | print("Total size of bidspace:" + str(domainsize))
|
---|
97 | print("Result size: " + str(list.size()))
|
---|