teambuilding/brute_force.py

118 lines
3.7 KiB
Python

import numpy as np
import json
import itertools
from pathlib import Path
from rich.console import Console
from rich.table import Table
from rich.text import Text
from rich import box
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
# people = {
# player: rgen.choice(players, size=n_prefs, replace=False) for player in players
# }
def team_table(mean, team0, team1):
console = Console(record=True)
console.print(Text(f"mean wishes fulfilled: {score:.02f}"))
for i, team in enumerate([team0, team1]):
table = Table(title=f"Team {i}", box=box.ROUNDED, show_lines=True)
table.add_column("player", justify="right", style="cyan")
table.add_column("wishes fulfilled", justify="center", style="magenta")
table.add_column("in %", justify="center", style="green")
for p in sorted(list(team)):
prefs = people[p]
matches = sum([pref in team for pref in people[p]])
table.add_row(
p, f"{matches:d}", f"{matches/len(prefs):.2%}" if prefs else ""
)
console.print(table)
console.save_html("tables.html")
def team_table_json():
players, preferences = load_stats()
mean, team0, team1 = apply_brute_force(players, preferences)
data = {}
for i, team in enumerate([team0, team1]):
tablename = f"Team {i+1}"
data[tablename] = []
for p in sorted(list(team)):
prefs = preferences[p]
matches = sum([pref in team for pref in preferences[p]])
data[tablename].append([p, matches, len(prefs)])
with open("prefs_page/src/table.json", "w") as f:
json.dump(data, f)
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_score = [(0, [], [])]
best_percentage = [(0, [], [])]
for team0 in itertools.combinations(players, 9):
team1 = {player for player in players if player not in team0}
score, percentage = evaluate_teams(team0, team1)
if score > best_score[0][0]:
best_score = [(score, team0, team1)]
if score == best_score[0][0] and set(team0) != set(best_score[0][1]):
best_score.append((score, team0, team1))
if percentage > best_percentage[0][0]:
best_percentage = [(percentage, team0, team1)]
if percentage == best_percentage[0][0] and set(team0) != set(best_score[0][1]):
best_percentage.append((percentage, team0, team1))
for result in best_score:
print(result[0])
print(result[1])
print(result[2])
for result in best_percentage:
print(result[0])
print(result[1])
print(result[2])
# team_table(score, team0, team1)
return best_score[0]
if __name__ == "__main__":
team_table_json()