-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathbasic_optimize.py
More file actions
153 lines (124 loc) · 5.19 KB
/
basic_optimize.py
File metadata and controls
153 lines (124 loc) · 5.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import csv
import sys
import itertools
import numpy as np
from utils import time_and_slow_calls
import pdb
pry = pdb.set_trace
def index_generator(ind_lists):
return itertools.product(*ind_lists)
def calculate_position_combinations(player_combinations, test_salary, num_players):
'''
Loop through the combinations of the single position, and if it's under
the test_salary and has more points than the current best combination set
those values. Returns an array of the best.
'''
#loop through the list of players that are of that posision
top_points = 0
top_sal = 0
top_players = [-1] * num_players
player_index_lists = [list(range(0, len(player_combinations)))] * num_players
for indicies in index_generator(player_index_lists):
if len(set(indicies)) != len(indicies):
continue
if indicies[0] > indicies[-1]:
continue
test_players = [player_combinations[index] for index in indicies] #grab the two testers
combined_salary = sum([p['sal'] for p in test_players])
if combined_salary > test_salary:
continue
points = sum([p['pts'] for p in test_players])
if points > top_points:
top_players = [p['pid'] for p in test_players]
top_points = points
top_sal = sum([p['sal'] for p in test_players])
return [test_salary, top_sal, top_points, top_players]
def combine_single_position(players, num_players):
'''
Goal is to have it where the for each salary in the range, have a list of the num_players
player ids who have the best combined points where their combined salary is below the salary
total.
#array of sets where (max_salary, combined salary, [list of pids], total_points)
'''
sal_ranges = range(3500*num_players, 60000 + 100, 100)
return [calculate_position_combinations(players, sal, num_players) for sal in sal_ranges]
def calculate_max_points(pos1, pos2, test_salary):
'''
Double loop so we test each combination of the two sets of positions.
We store the information for each new max point combinations, as long as
they're under the test_salary limit, and return those fields.
'''
top_points = 0
for g1 in pos1: #g1 stands for group 1
for g2 in pos2:
#break if combined salary is above the test_salary
if g1[1] + g2[1] > test_salary:
#thankfully we can break if we've hit the point where the combined salary is bigger
#because the positions are sorted by salary
break
points = g1[2] + g2[2]
#if the two point totals added together > current max point total
if points > top_points:
top_players = g1[3] + g2[3]
top_points = points
top_sal = g1[1] + g2[1]
return [test_salary, top_sal, top_points, top_players]
def combine_multiple_positions(pos1, pos2):
num_players = len(pos1[0][3]) + len(pos2[0][3]) #counting the number of pids in those arrays
max_salary = min(60000 + 100, 13000 * num_players) #if we're only testing 3 players, the max salary they can have combined is 13000 * 3
sal_ranges = range(3500*num_players, max_salary, 100)
return [calculate_max_points(pos1, pos2, salary) for salary in sal_ranges]
@time_and_slow_calls
def optimize(pgs, sgs, sfs, pfs, cs):
print("Calculating initial PGs")
pgt = combine_single_position(pgs, 2)
print("Calculating initial SGs")
sgt = combine_single_position(sgs, 2)
print("Calculating initial SFs")
sft = combine_single_position(sfs, 2)
print("Calculating initial PFs")
pft = combine_single_position(pfs, 2)
print("Calculating initial Cs")
ct = combine_single_position(cs, 1)
print("Combining PGs and SGs")
pgsg = combine_multiple_positions(pgt, sgt)
print("Combining PFs and SFs")
sfpf = combine_multiple_positions(sft, pft)
print("Combining PFs, SFs, and Cs")
sfpfc = combine_multiple_positions(sfpf, ct)
print("Combining all positions")
fin = combine_multiple_positions(pgsg, sfpfc)
return fin
if __name__ == '__main__':
opt_date = sys.argv[1] #always assuming there's a date passed from the command line
data_filename = f"data/{opt_date}.csv"
dbid = {} #used for showing the winners at the end
pgs = []
sgs = []
sfs = []
pfs = []
cs = []
with open(data_filename) as csv_file:
csv_reader = csv.DictReader(csv_file)
rows = list(csv_reader)
for row in reversed(rows):
dbid[int(row['pid'])] = row
row['pid'] = int(row['pid'])
row['sal'] = int(row['sal'])
row['pts'] = float(row['pts'])
if row['pos'] == 'PG':
pgs.append(row)
elif row['pos'] == 'SG':
sgs.append(row)
elif row['pos'] == 'SF':
sfs.append(row)
elif row['pos'] == 'PF':
pfs.append(row)
elif row['pos'] == 'C':
cs.append(row)
fin = optimize(pgs, sgs, sfs, pfs, cs)
print(fin[-1])
pids = fin[-1][3]
for pid in pids:
pinfo = dbid[pid]
print(pinfo['name'], pinfo['pos'], pinfo['sal'], pinfo['pts'])