source: ANL2022/procrastin_agent/utils/time_estimator.py

Last change on this file was 75, checked in by wouter, 21 months ago

#6 added ANAC2022 parties

File size: 7.3 KB
Line 
1import numpy as np
2from sklearn.linear_model import LinearRegression
3
4"""
5Key assumptions:
61. turns_left will only be called during our agent's "turn"
72. times will be added to their respective lists using the progress function
8"""
9class TimeEstimator:
10
11 def __init__(self):
12 self.self_times = []
13 self.rounds = []
14 #self.roundsquare = []
15 # self.outliers = []
16 self.opp_times = []
17 self.self_diff = []
18 self.FRAME_LENGTHS = [10000, 100]
19 self.UPDATE_PERIODS = [1, 1]
20 self.models = [None for _ in range(len(self.FRAME_LENGTHS))]
21 self.stdevs = [None for _ in range(len(self.FRAME_LENGTHS))]
22 self.self_times_adj = []
23 self.opp_times_adj = []
24
25 self.round_count = 0
26 self.outlier_count = 0
27 self.time_factor = 1.0
28
29 def update_time_factor(self, time_factor: float):
30 self.time_factor = time_factor
31
32 def get_new_time_factor(self, predicted_negs_left: list, bid_pool_size: int):
33 if len(predicted_negs_left) > bid_pool_size:
34 return self.time_factor / max((predicted_negs_left[-bid_pool_size] / bid_pool_size), 0.01)
35 elif len(predicted_negs_left) > 10:
36 return self.time_factor / max((predicted_negs_left[5] / (len(predicted_negs_left) - 5)), 0.01)
37 elif len(predicted_negs_left):
38 return self.time_factor / max(predicted_negs_left[-1], 0.01)
39 else:
40 return self.time_factor
41
42 def self_times_add(self, time: float):
43 self.round_count += 1
44 self.self_times.append(time)
45 self.rounds.append(self.round_count)
46 if self.round_count > 5 and time > np.mean(self.self_times) + 3 * np.std(self.self_times):
47 self.outlier_count += 1
48 # self.outliers.append(self.outlier_count)
49 #self.roundsquare.append(self.round_count * self.round_count)
50
51 self.update_model()
52
53 def opp_times_add(self, value: float):
54 self.opp_times.append(value)
55 self.self_diff.append(value - self.self_times[-1])
56
57 def _generate_model(self, frame_length):
58 y_list = self.self_times if len(self.self_times) < frame_length else self.self_times[-frame_length:]
59 x1_list = self.rounds if len(self.rounds) < frame_length else self.rounds[-frame_length:]
60 # x2_list = self.roundsquare if len(self.roundsquare) < frame_length else self.rounds[-frame_length:]
61 y = np.array(y_list)
62 x1 = np.array(x1_list)
63 # x2 = np.array(x2_list)
64 # X = np.stack([x1, x2]).transpose((1,0))
65 X = np.array([x1]).transpose((1,0))
66 model1 = LinearRegression().fit(X, y)
67 # model2 = LinearRegression().fit(X2, y)
68 y_pred = model1.predict(X)
69 res = y_pred - y
70 stdev = np.std(res)
71 return model1, stdev
72
73 def update_model(self):
74 issue_count = len(self.self_times)
75 for i, (frame_length, update_period) in enumerate(zip(self.FRAME_LENGTHS, self.UPDATE_PERIODS)):
76 if issue_count % update_period == 0 or i < 5:
77 model, stdev = self._generate_model(frame_length)
78 self.models[i] = model
79 self.stdevs[i] = stdev
80
81 def turns_left(self, time):
82 """
83 If your turn starts at time, how many turns are left?
84 """
85 if len(self.self_times) <= 1:
86 return 2000
87 p_list = [np.append(model.coef_, model.intercept_ - 1.0) for model in self.models]
88 # final_turn_counts = np.array([np.max(np.roots(p)) / (1.0 + stdev) for p, stdev in zip(p_list, self.stdevs)])
89 final_turn_counts = np.array([np.max(np.roots(p)) / (1.0 + stdev) * self.time_factor for p, stdev in zip(p_list, self.stdevs)])
90
91 p_list = [np.append(model.coef_, model.intercept_ - time) for model in self.models]
92 # time_turn_counts = np.array([np.max(np.roots(p)) / (1.0 + stdev) for p, stdev in zip(p_list, self.stdevs)])
93 time_turn_counts = np.array([np.max(np.roots(p)) / (1.0 + stdev) * self.time_factor for p, stdev in zip(p_list, self.stdevs)])
94
95 return int(np.min(final_turn_counts - time_turn_counts))
96
97 # #adds adjusted values to the adjusted lists by subtracting the "start point" provided by the preceding progress value from each value
98 # def lists_adjust(self):
99 # #first iteration
100 # if self.idx == 0:
101 # #our agent made the first bid
102 # if self.self_times[0] < self.opp_times[0]:
103 # self.self_times_adj.append(self.self_times[0])
104 # self.opp_times_adj.append(self.opp_times[self.idx] - self.self_times[self.idx])
105 # self.idx += 1
106 # while self.idx < len(self.self_times):
107 # self.self_times_adj.append(self.self_times[self.idx]-self.opp_times[self.idx-1])
108 # self.opp_times_adj.append(self.opp_times[self.idx]-self.self_times[self.idx])
109 # self.idx += 1
110 # #the opponent made the first bid
111 # else:
112 # self.self_times_adj.append(self.self_times[self.idx]-self.opp_times[self.idx])
113 # self.opp_times_adj.append(self.opp_times[0])
114 # self.opp_times_adj.append(self.opp_times[self.idx+1]-self.self_times[self.idx])
115 # self.idx += 1
116 # while self.idx < len(self.self_times):
117 # self.self_times_adj.append(self.self_times[self.idx]-self.opp_times[self.idx])
118 # self.opp_times_adj.append(self.opp_times[self.idx+1]-self.self_times[self.idx])
119 # self.idx += 1
120 # #further iterations
121 # else:
122 # #continuing case where our agent made the first bid
123 # if self.self_times[self.idx] < self.opp_times[self.idx]:
124 # while self.idx < len(self.self_times):
125 # self.self_times_adj.append(self.self_times[self.idx]-self.opp_times[self.idx-1])
126 # self.opp_times_adj.append(self.opp_times[self.idx]-self.self_times[self.idx])
127 # self.idx += 1
128 # #cintinuing case where opponent made the first bid
129 # else:
130 # while self.idx < len(self.self_times):
131 # self.self_times_adj.append(self.self_times[self.idx]-self.opp_times[self.idx])
132 # self.opp_times_adj.append(self.opp_times[self.idx+1]-self.self_times[self.idx])
133 # self.idx += 1
134
135 # #feeder function to be deleted after regression implemented
136 # def opp_avg(self):
137 # Sum = sum(self.opp_times_adj)
138 # O_avg = Sum / len(self.opp_times_adj)
139 # return O_avg
140
141 # #feeder function to be deleted after regression implemented
142 # def self_avg(self):
143 # Sum = sum(self.self_times_adj)
144 # S_avg = Sum/len(self.self_times_adj)
145 # return S_avg
146
147 # def turns_left(self, progress: float):
148 # self.lists_adjust()
149 # opp_time = self.opp_avg()
150 # self_time = self.self_avg()
151 # i = 0
152 # count = 0
153
154 # #make sure order is correct
155 # while progress < 1:
156 # if (i % 2 == 0):
157 # progress += self_time
158 # else:
159 # progress += opp_time
160
161 # count += 1
162 # i += 1
163
164 # return count
Note: See TracBrowser for help on using the repository browser.