-
Notifications
You must be signed in to change notification settings - Fork 0
/
match_track.py
92 lines (54 loc) · 2.09 KB
/
match_track.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
from scipy.optimize import linear_sum_assignment
from collections import defaultdict
import pandas as pd
import numpy as np
df = pd.read_csv("cassoela - Form.csv")
tracks = np.array([c for c in df.columns if "Strecke" in c])
df_subset = df[["Name"] + list(tracks)]
df_subnp = df_subset.to_numpy()
names = df_subnp[:,0]
preferences = df_subnp[:,1:]
degrees = {
"Really don't want": 0,
"Prefer not": 1,
"Can": 2,
"Would like": 3,
"Would really love": 4,
}
weights = np.zeros_like(preferences, dtype=np.int8)
for txt, val in degrees.items():
weights[preferences == txt] = val
any_track_runner = defaultdict(set)
best_matching = linear_sum_assignment(weights, True)
best_score = weights[best_matching].sum()
track_runner = {}
combos = defaultdict(list)
for runner_i, track_i in zip(*best_matching):
combos[names[runner_i]].append(tracks[track_i])
any_track_runner[names[runner_i]].add(tracks[track_i])
any_track_runner[tracks[track_i]].add(names[runner_i])
for run_i, tr_i in zip(*best_matching):
new_weights = weights.copy()
new_weights[run_i, tr_i] = 0
while True:
track_runner = {}
matching = linear_sum_assignment(new_weights, True)
score = new_weights[matching].sum()
if score < best_score:
break
old_score = score
for runner_i, track_i in zip(*matching):
combos[names[runner_i]].append(tracks[track_i])
any_track_runner[names[runner_i]].add(tracks[track_i])
any_track_runner[tracks[track_i]].add(names[runner_i])
tr_i_ = matching[1][run_i]
new_weights[run_i, tr_i_] = 0
df_possibilities = pd.DataFrame(columns=tracks, index=names)
df_possibilities = df_possibilities.fillna("")
for i_n, name in enumerate(names):
for track in any_track_runner[name]:
df_possibilities.loc[name, track] = weights[i_n, list(tracks).index(track)]
df_combos = pd.DataFrame(combos)
df_combos.to_csv("combos.csv")
print(f"Found {len(df_combos)} optimal combinations.")
df_possibilities.to_csv("possibilities.csv", sep="\t")