def fitness(self, player_ids): """PyGMO required function. The objective function to minimise. In this case: - 0 if the proposed squad isn't valid - weghted sum of gameweek points otherwise """ # Make squad from player IDs squad = Squad(budget=self.budget, season=self.season) for idx in player_ids: add_ok = squad.add_player( self.players[int(idx)].player_id, gameweek=self.start_gw, ) if not add_ok: return [0] # fill empty slots with dummy players (if chosen not to optimise full squad) for pos in self.positions: if self.dummy_per_position[pos] > 0: for _ in range(self.dummy_per_position[pos]): dp = DummyPlayer( self.gw_range, self.tag, pos, price=self.dummy_sub_cost ) add_ok = squad.add_player(dp) if not add_ok: return [0] # Check squad is valid, if not return fitness of zero if not squad.is_complete(): return [0] # Calc expected points for all gameweeks # - weight each gw points by its gw_weight # - weight each sub by their sub_weight score = 0.0 for i, gw in enumerate(self.gw_range): gw_weight = self.gw_weight[i] if gw == self.bench_boost_gw: score += gw_weight * squad.get_expected_points( gw, self.tag, bench_boost=True ) elif gw == self.triple_captain_gw: score += gw_weight * squad.get_expected_points( gw, self.tag, triple_captain=True ) else: score += gw_weight * squad.get_expected_points(gw, self.tag) if gw != self.bench_boost_gw: score += gw_weight * squad.total_points_for_subs( gw, self.tag, sub_weights=self.sub_weights ) return [-score]
def get_lineup_from_payload(lineup): """ inverse of build_lineup_payload. Returns a squad object from get_lineup lineup is a dictionary, with the entry "picks" being a list of dictionaries like: {"element":353,"position":1,"selling_price":55,"multiplier":1,"purchase_price":55,"is_captain":false,"is_vice_captain":false} """ s = Squad() for p in lineup["picks"]: player = get_player_from_api_id(p["element"]) s.add_player(player, check_budget=False) if s.is_complete(): return s else: raise RuntimeError("Squad incomplete")
def make_new_squad_iter( gw_range, tag, budget=1000, season=CURRENT_SEASON, num_iterations=100, update_func_and_args=None, verbose=False, bench_boost_gw=None, triple_captain_gw=None, **kwargs, ): """ Make a squad from scratch, i.e. for gameweek 1, or for wildcard, or free hit, by selecting high scoring players and then iteratively replacing them with cheaper options until we have a valid squad. """ transfer_gw = min(gw_range) # the gw we're making the new squad best_score = 0.0 best_squad = None for iteration in range(num_iterations): if verbose: print("Choosing new squad: iteration {}".format(iteration)) if update_func_and_args: # call function to update progress bar. # this was passed as a tuple (func, increment, pid) update_func_and_args[0](update_func_and_args[1], update_func_and_args[2]) predicted_points = {} t = Squad(budget, season=season) # first iteration - fill up from the front for pos in positions: predicted_points[pos] = get_predicted_points(gameweek=gw_range, position=pos, tag=tag, season=season) for pp in predicted_points[pos]: t.add_player(pp[0], gameweek=transfer_gw) if t.num_position[pos] == TOTAL_PER_POSITION[pos]: break # presumably we didn't get a complete squad now excluded_player_ids = [] while not t.is_complete(): # randomly swap out a player and replace with a cheaper one in the # same position player_to_remove = t.players[random.randint(0, len(t.players) - 1)] remove_cost = player_to_remove.purchase_price t.remove_player(player_to_remove.player_id, gameweek=transfer_gw) excluded_player_ids.append(player_to_remove.player_id) for pp in predicted_points[player_to_remove.position]: if (pp[0] not in excluded_player_ids or random.random() < 0.3): # some chance to put player back cp = CandidatePlayer(pp[0], gameweek=transfer_gw, season=season) if cp.purchase_price >= remove_cost: continue else: t.add_player(pp[0], gameweek=transfer_gw) # now try again to fill up the rest of the squad for pos in positions: num_missing = TOTAL_PER_POSITION[pos] - t.num_position[pos] if num_missing == 0: continue for pp in predicted_points[pos]: if pp[0] in excluded_player_ids: continue t.add_player(pp[0], gameweek=transfer_gw) if t.num_position[pos] == TOTAL_PER_POSITION[pos]: break # we have a complete squad score = 0.0 for gw in gw_range: if gw == bench_boost_gw: score += t.get_expected_points( gw, tag, bench_boost=True) * get_discount_factor( gw_range[0], gw) elif gw == triple_captain_gw: score += t.get_expected_points( gw, tag, triple_captain=True) * get_discount_factor( gw_range[0], gw) else: score += t.get_expected_points(gw, tag) * get_discount_factor( gw_range[0], gw) if score > best_score: best_score = score best_squad = t if verbose: print("====================================\n") print(best_squad) print(best_score) return best_squad