-
Notifications
You must be signed in to change notification settings - Fork 113
/
optimize.py
163 lines (132 loc) · 4.56 KB
/
optimize.py
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
153
154
155
156
157
158
159
160
161
162
163
import random
from copy import deepcopy
from typing import List
from draftfast import player_pool as pool
from draftfast.orm import RosterSelect, Roster
from draftfast.optimizer import Optimizer
from draftfast.exposure import (
check_exposure,
get_exposure_table,
get_exposure_matrix,
get_exposure_args,
)
from draftfast.rules import RuleSet
from draftfast.settings import PlayerPoolSettings, OptimizerSettings
from draftfast.lineup_constraints import LineupConstraints
def run(
rule_set: RuleSet,
player_pool: list,
constraints: LineupConstraints = LineupConstraints(),
optimizer_settings: OptimizerSettings = OptimizerSettings(),
player_settings: PlayerPoolSettings = PlayerPoolSettings(),
exposure_dict: dict = dict(),
roster_gen: Roster = None,
verbose=False,
) -> Roster:
players = player_pool
if player_settings.exist() or constraints.exist():
players = pool.filter_pool(
deepcopy(player_pool),
player_settings,
)
if not isinstance(rule_set, RuleSet):
raise Exception("RuleSet not defined. Please refer to the docs")
if rule_set.game_type == "showdown":
if optimizer_settings.no_offense_against_defense:
print("WARNING:")
print("no_offense_against_defense setting ignored for showdown")
print("game types. Use no_defense_against_captain instead.")
print()
optimizer = Optimizer(
players=players,
rule_set=rule_set,
settings=optimizer_settings,
lineup_constraints=constraints,
exposure_dict=exposure_dict,
)
variables = optimizer.variables
if optimizer.solve():
if roster_gen:
roster = roster_gen()
else:
roster = RosterSelect().roster_gen(rule_set.league)
for i, player in enumerate(players):
if variables[i].solution_value() == 1:
roster.add_player(player)
if verbose:
print("Optimal roster for: {}".format(rule_set.league))
print(roster)
return roster
if verbose:
print(
f"""
No solution found.
Try adjusting your query by taking away constraints.
OPTIMIZER CONSTRAINTS:
Minimum teams: {rule_set.min_teams or optimizer_settings.min_teams}
Other optimizer contraints: {optimizer_settings}
LINEUP CONSTRAINTS:
{constraints}
PLAYER POOL SETTINGS:
{players}
PLAYER COUNT: {len(players or [])}
""")
return None
def run_multi(
iterations: int,
rule_set: RuleSet,
player_pool: list,
constraints: LineupConstraints = LineupConstraints(),
player_settings: PlayerPoolSettings = PlayerPoolSettings(),
optimizer_settings: OptimizerSettings = OptimizerSettings(),
verbose=False,
exposure_bounds: List[dict] = list(),
exposure_random_seed=None,
) -> [List[Roster], list]:
if not isinstance(rule_set, RuleSet):
raise Exception("RuleSet not defined. Please refer to the docs")
# set the random seed globally for random lineup exposure
random.seed(exposure_random_seed)
rosters = []
for _ in range(0, iterations):
exposure_dict = get_exposure_args(
existing_rosters=optimizer_settings.existing_rosters,
exposure_bounds=exposure_bounds,
n=iterations,
use_random=bool(exposure_random_seed),
random_seed=exposure_random_seed,
)
roster = run(
rule_set=rule_set,
player_pool=player_pool,
optimizer_settings=optimizer_settings,
player_settings=player_settings,
exposure_dict=exposure_dict,
constraints=constraints,
verbose=verbose,
)
if roster:
optimizer_settings.existing_rosters += [roster]
if roster:
rosters.append(roster)
else:
break
# clear ban/lock to reset exposure between iterations
reset_player_ban_lock(player_pool)
exposure_diffs = {}
if rosters and verbose:
print(get_exposure_table(rosters, exposure_bounds))
print()
print(get_exposure_matrix(rosters))
print()
exposure_diffs = check_exposure(rosters, exposure_bounds)
for n, d in exposure_diffs.items():
if d < 0:
print("{} is UNDER exposure by {} lineups".format(n, d))
else:
print("{} is OVER exposure by {} lineups".format(n, d))
return rosters, exposure_diffs
def reset_player_ban_lock(player_pool):
for p in player_pool:
p.ban = False
p.lock = False