X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=roster%2Ftest.py;fp=roster%2Ftest.py;h=dd90b4325de83a6d3d44528c551df0df84dad8d7;hb=b2f520916cf152c9d2c868f9181369127b485a12;hp=0000000000000000000000000000000000000000;hpb=74ac454c782401f07e3c26353073a4645c8b825a;p=ultimatescore diff --git a/roster/test.py b/roster/test.py new file mode 100644 index 0000000..dd90b43 --- /dev/null +++ b/roster/test.py @@ -0,0 +1,160 @@ +from __future__ import print_function +import sys +from ortools.constraint_solver import pywrapcp + +def print_solution(sol): + for i in range(num_matches): + home_team = collector.Value(sol, home_teams[i]) + away_team = collector.Value(sol, away_teams[i]) + matchnum = collector.Value(sol, matchnums[i]) + #print("%2d. %d vs. %d (matchnum %d)" % (i, home_team, away_team, matchnum)) + print("%2d. %d vs. %d (matchnum %2d, excitedness %d)" % (i, home_team, away_team, matchnum, excitedness[matchnum])) + +# Creates the solver. +solver = pywrapcp.Solver("schedule_shifts") + +num_teams = 6 +num_matches = (num_teams * (num_teams - 1)) // 2 + +# Create supermatch variables. +matchnums = [] +for match_idx in range(num_matches): + matchnums.append(solver.IntVar(0, num_matches - 1, "matchnum(%i)" % (match_idx))) +solver.Add(solver.AllDifferent(matchnums)); + +# Create list of matches. +match_num = 0 +excitedness = [] +home_teams_for_match_num = [] +away_teams_for_match_num = [] +for team_idx_1 in range(num_teams): + for team_idx_2 in range(num_teams): + if team_idx_2 > team_idx_1: + home_teams_for_match_num.append(team_idx_1) + away_teams_for_match_num.append(team_idx_2) + if team_idx_2 - team_idx_1 == 1: + excitedness.append(5) + elif team_idx_2 - team_idx_1 == 2: + excitedness.append(2) + else: + excitedness.append(0) + print("matchnum ", match_num , " plays: ", team_idx_1, " - ", team_idx_2, " excited: " , excitedness[match_num]) + match_num = match_num + 1 + +# Create match variables. +home_teams = [] +away_teams = [] +for match_idx in range(num_matches): + home_teams.append(solver.IntVar(0, num_teams - 1, "home_team_on_match(%i)" % (match_idx))) + away_teams.append(solver.IntVar(0, num_teams - 1, "away_team_on_match(%i)" % (match_idx))) +matches_flat = home_teams + away_teams + +for match_num in range(num_matches): + # home_teams_var[i] = home_teams[match_num_var[i]] + #solver.Add(matchnums[match_num].IndexOf(home_teams) == team_idx_1) # home_teams[matchnums[match_num]] == team_idx_1 + #solver.Add(matchnums[match_num].IndexOf(away_teams) == team_idx_2) + solver.Add(home_teams[match_num] == solver.Element(home_teams_for_match_num, matchnums[match_num])) + solver.Add(away_teams[match_num] == solver.Element(away_teams_for_match_num, matchnums[match_num])) + +## A team can never play two matches in a row +for match_idx in range(num_matches - 1): + solver.Add(home_teams[match_idx] != home_teams[match_idx + 1]) + solver.Add(away_teams[match_idx] != home_teams[match_idx + 1]) + solver.Add(home_teams[match_idx] != away_teams[match_idx + 1]) + solver.Add(away_teams[match_idx] != away_teams[match_idx + 1]) + +# More waiting time is good +tired_matches = [] +for match_idx in range(num_matches - 2): + home_tired = ( + (home_teams[match_idx] == home_teams[match_idx + 2]) + + (home_teams[match_idx] == away_teams[match_idx + 2])) + away_tired = ( + (away_teams[match_idx] == home_teams[match_idx + 2]) + + (away_teams[match_idx] == away_teams[match_idx + 2])) + tired_matches.append(home_tired) + tired_matches.append(away_tired) + + # double-tired is not cool + if match_idx < num_matches - 4: + home_doubletired = home_tired * ( + (home_teams[match_idx] == home_teams[match_idx + 4]) + + (home_teams[match_idx] == away_teams[match_idx + 4])) + away_doubletired = away_tired * ( + (away_teams[match_idx] == home_teams[match_idx + 4]) + + (away_teams[match_idx] == away_teams[match_idx + 4])) + tired_matches.append(home_doubletired * 100) + tired_matches.append(away_doubletired * 100) + +sum_tiredness = solver.Sum(tired_matches) + +## TFK can not play the first match +solver.Add(home_teams[0] != 0) +solver.Add(away_teams[0] != 0) +solver.Add(home_teams[1] != 0) +solver.Add(away_teams[1] != 0) + +# Group final comes last +solver.Add(home_teams[num_matches - 1] == 0) +solver.Add(away_teams[num_matches - 1] == 1) + +# Put the more excitedness last +sum_excitedness = solver.Sum([(matchnums[match_num].IndexOf(excitedness) * match_num) for match_num in range(num_matches)]) +objective = solver.Maximize(sum_excitedness - 10 * sum_tiredness, 1) + +# TODO: AllowedAssignments +# TODO: multiple fields/groups, objectives of getting TV time (esp. for interesting matches) +# TODO: objective on getting more interesting matches last + +db = solver.Phase(matchnums, solver.CHOOSE_FIRST_UNBOUND, + solver.ASSIGN_MIN_VALUE) +search_log = solver.SearchLog(1000000, objective) +#global_limit = solver.TimeLimit(1000) +global_limit = solver.TimeLimit(100000000) + +## Create the solution collector. +#solution = solver.Assignment() +#solution.Add(matches_flat) +#solution.Add(matchnums) +# +##collector = solver.AllSolutionCollector(solution) +##collector = solver.LastSolutionCollector(solution) +#collector = solver.FirstSolutionCollector(solution) +# +#solver.Solve(db, [collector, search_log, objective, global_limit]) +#print("Solutions found:", collector.SolutionCount()) +#print("Time:", solver.WallTime(), "ms") +#print() +## Display a few solutions picked at random. +#a_few_solutions = [0] +#for sol in a_few_solutions: +# print_solution(sol) +# +#os.exit(0) + +###All +solver.NewSearch(db, [search_log, objective, global_limit]) +num_solutions = 0 +while solver.NextSolution(): + #print("objective = ", sum_excitedness.Value()) + for i in range(num_matches): + home_team = home_teams[i].Value() + away_team = away_teams[i].Value() + matchnum = matchnums[i].Value() + + tiredness = 0 + if i >= 2: + if home_team == home_teams[i - 2].Value(): + tiredness = tiredness + 1 + if home_team == away_teams[i - 2].Value(): + tiredness = tiredness + 1 + if away_team == home_teams[i - 2].Value(): + tiredness = tiredness + 1 + if away_team == away_teams[i - 2].Value(): + tiredness = tiredness + 1 + + print("%2d. %d vs. %d (matchnum %2d, excitedness %d, tiredness %d)" % (i, home_team, away_team, matchnum, excitedness[matchnum], tiredness)) + + print() + num_solutions += 1 +solver.EndSearch()