teambuilding/brute_force.py

120 lines
3.7 KiB
Python

import numpy as np
import json
import itertools
from pathlib import Path
rgen = np.random.default_rng(seed=42)
def load_stats():
db = Path("local_team.db")
players_list = "prefs_page/src/players.json"
with open(players_list, "r") as f:
players = json.load(f)
preferences = {}
for line in open(db, "r"):
date, person, prefs = line.split("\t")
if not person.strip() or not prefs.strip():
continue
preferences[person] = [p.strip() for p in prefs.split(",")]
for player in players:
if player not in preferences:
preferences[player] = []
return players, preferences
# synthetical data
# rgen = np.random.default_rng(seed=42)
# n_prefs = 8
# preferences = {
# player: rgen.choice(players, size=n_prefs, replace=False) for player in players
# }
def team_table_json():
players, preferences = load_stats()
best = apply_brute_force(players, preferences)
data = {k: {} for k in best}
for k, v in best.items():
mean, team0, team1 = v[0]
overall_matches = 0
overall_preference_statements = 0
for i, team in enumerate([team0, team1]):
tablename = f"Team {i+1}"
data[k][tablename] = []
for p in sorted(list(team)):
prefs = preferences[p]
matches = sum([pref in team for pref in preferences[p]])
data[k][tablename].append([p, matches, len(prefs)])
overall_matches += matches
overall_preference_statements += len(prefs)
# data[k]["overall_matches"] = overall_matches
# data[k]["overall_preference_statements"] = overall_preference_statements
with open("prefs_page/src/table.json", "w") as f:
json.dump(data, f)
def unique_names(team):
"""check if first names are unique"""
return len(set(team)) == len(set([p.split()[0] for p in team]))
def apply_brute_force(players, preferences):
def evaluate_teams(team0, team1):
scores = []
percentages = []
for team in [team0, team1]:
for p in team:
scores.append(sum([pref in team for pref in preferences[p]]))
if len(preferences[p]) > 0:
percentages.append(scores[-1] / len(preferences[p]))
return np.mean(scores), np.mean(percentages) * 100
best = {
f"{i},{j}": [(0, [], [])]
for i, j in itertools.product(["total", "relative"], ["unique", "non-unique"])
}
for team0 in itertools.combinations(players, 9):
team1 = {player for player in players if player not in team0}
score, percentage = evaluate_teams(team0, team1)
for k, v in best.items():
if k.startswith("total"):
meassure = score
elif k.startswith("relative"):
meassure = percentage
if meassure > best[k][0][0]:
if k.endswith(",unique") and not (
unique_names(team0) and unique_names(team1)
):
continue
best[k] = [(meassure, team0, team1)]
elif meassure == best[k][0][0] and set(team0) != set(best[k][0][1]):
if k.endswith(",unique") and not (
unique_names(team0) and unique_names(team1)
):
continue
best[k].append((meassure, team0, team1))
if __name__ == "__main__":
for k, v in best.items():
print("##", k)
for result in v:
print(result[0])
print(sorted(result[1]))
print(sorted(result[2]))
print()
# team_table(score, team0, team1)
return best
if __name__ == "__main__":
team_table_json()