]> git.sesse.net Git - ultimatescore/blob - roster/test.py
dd90b4325de83a6d3d44528c551df0df84dad8d7
[ultimatescore] / roster / test.py
1 from __future__ import print_function
2 import sys
3 from ortools.constraint_solver import pywrapcp
4
5 def print_solution(sol):
6   for i in range(num_matches):
7     home_team = collector.Value(sol, home_teams[i])
8     away_team = collector.Value(sol, away_teams[i])
9     matchnum = collector.Value(sol, matchnums[i])
10     #print("%2d. %d vs. %d   (matchnum %d)" % (i, home_team, away_team, matchnum))
11     print("%2d. %d vs. %d   (matchnum %2d, excitedness %d)" % (i, home_team, away_team, matchnum, excitedness[matchnum]))
12
13 # Creates the solver.
14 solver = pywrapcp.Solver("schedule_shifts")
15
16 num_teams = 6
17 num_matches = (num_teams * (num_teams - 1)) // 2
18
19 # Create supermatch variables.
20 matchnums = []
21 for match_idx in range(num_matches):
22   matchnums.append(solver.IntVar(0, num_matches - 1, "matchnum(%i)" % (match_idx)))
23 solver.Add(solver.AllDifferent(matchnums));
24
25 # Create list of matches.
26 match_num = 0
27 excitedness = []
28 home_teams_for_match_num = []
29 away_teams_for_match_num = []
30 for team_idx_1 in range(num_teams):
31   for team_idx_2 in range(num_teams):
32     if team_idx_2 > team_idx_1:
33       home_teams_for_match_num.append(team_idx_1)
34       away_teams_for_match_num.append(team_idx_2)
35       if team_idx_2 - team_idx_1 == 1:
36         excitedness.append(5)
37       elif team_idx_2 - team_idx_1 == 2:
38         excitedness.append(2)
39       else:
40         excitedness.append(0)
41       print("matchnum ", match_num , " plays: ", team_idx_1, " - ", team_idx_2, "  excited: " , excitedness[match_num])
42       match_num = match_num + 1
43
44 # Create match variables.
45 home_teams = []
46 away_teams = []
47 for match_idx in range(num_matches):
48   home_teams.append(solver.IntVar(0, num_teams - 1, "home_team_on_match(%i)" % (match_idx)))
49   away_teams.append(solver.IntVar(0, num_teams - 1, "away_team_on_match(%i)" % (match_idx)))
50 matches_flat = home_teams + away_teams
51
52 for match_num in range(num_matches):
53   # home_teams_var[i] = home_teams[match_num_var[i]]
54   #solver.Add(matchnums[match_num].IndexOf(home_teams) == team_idx_1)  # home_teams[matchnums[match_num]] == team_idx_1
55   #solver.Add(matchnums[match_num].IndexOf(away_teams) == team_idx_2)
56   solver.Add(home_teams[match_num] == solver.Element(home_teams_for_match_num, matchnums[match_num]))
57   solver.Add(away_teams[match_num] == solver.Element(away_teams_for_match_num, matchnums[match_num]))
58
59 ## A team can never play two matches in a row
60 for match_idx in range(num_matches - 1):
61   solver.Add(home_teams[match_idx] != home_teams[match_idx + 1])
62   solver.Add(away_teams[match_idx] != home_teams[match_idx + 1])
63   solver.Add(home_teams[match_idx] != away_teams[match_idx + 1])
64   solver.Add(away_teams[match_idx] != away_teams[match_idx + 1])
65
66 # More waiting time is good
67 tired_matches = []
68 for match_idx in range(num_matches - 2):
69   home_tired = (
70     (home_teams[match_idx] == home_teams[match_idx + 2]) +
71     (home_teams[match_idx] == away_teams[match_idx + 2]))
72   away_tired = (
73     (away_teams[match_idx] == home_teams[match_idx + 2]) +
74     (away_teams[match_idx] == away_teams[match_idx + 2]))
75   tired_matches.append(home_tired)
76   tired_matches.append(away_tired)
77
78   # double-tired is not cool
79   if match_idx < num_matches - 4:
80     home_doubletired = home_tired * (
81       (home_teams[match_idx] == home_teams[match_idx + 4]) +
82       (home_teams[match_idx] == away_teams[match_idx + 4]))
83     away_doubletired = away_tired * (
84       (away_teams[match_idx] == home_teams[match_idx + 4]) +
85       (away_teams[match_idx] == away_teams[match_idx + 4]))
86     tired_matches.append(home_doubletired * 100)
87     tired_matches.append(away_doubletired * 100)
88
89 sum_tiredness = solver.Sum(tired_matches)
90
91 ## TFK can not play the first match
92 solver.Add(home_teams[0] != 0)
93 solver.Add(away_teams[0] != 0)
94 solver.Add(home_teams[1] != 0)
95 solver.Add(away_teams[1] != 0)
96
97 # Group final comes last
98 solver.Add(home_teams[num_matches - 1] == 0)
99 solver.Add(away_teams[num_matches - 1] == 1)
100
101 # Put the more excitedness last
102 sum_excitedness = solver.Sum([(matchnums[match_num].IndexOf(excitedness) * match_num) for match_num in range(num_matches)])
103 objective = solver.Maximize(sum_excitedness - 10 * sum_tiredness, 1)
104
105 # TODO: AllowedAssignments
106 # TODO: multiple fields/groups, objectives of getting TV time (esp. for interesting matches)
107 # TODO: objective on getting more interesting matches last
108
109 db = solver.Phase(matchnums, solver.CHOOSE_FIRST_UNBOUND,
110                   solver.ASSIGN_MIN_VALUE)
111 search_log = solver.SearchLog(1000000, objective)
112 #global_limit = solver.TimeLimit(1000)
113 global_limit = solver.TimeLimit(100000000)
114
115 ## Create the solution collector.
116 #solution = solver.Assignment()
117 #solution.Add(matches_flat)
118 #solution.Add(matchnums)
119 #
120 ##collector = solver.AllSolutionCollector(solution)
121 ##collector = solver.LastSolutionCollector(solution)
122 #collector = solver.FirstSolutionCollector(solution)
123 #
124 #solver.Solve(db, [collector, search_log, objective, global_limit])
125 #print("Solutions found:", collector.SolutionCount())
126 #print("Time:", solver.WallTime(), "ms")
127 #print()
128 ## Display a few solutions picked at random.
129 #a_few_solutions = [0]
130 #for sol in a_few_solutions:
131 #  print_solution(sol)
132 #
133 #os.exit(0)
134
135 ###All
136 solver.NewSearch(db, [search_log, objective, global_limit])
137 num_solutions = 0
138 while solver.NextSolution():
139   #print("objective = ", sum_excitedness.Value())
140   for i in range(num_matches):
141     home_team = home_teams[i].Value()
142     away_team = away_teams[i].Value()
143     matchnum = matchnums[i].Value()
144
145     tiredness = 0
146     if i >= 2:
147       if home_team == home_teams[i - 2].Value():
148         tiredness = tiredness + 1
149       if home_team == away_teams[i - 2].Value():
150         tiredness = tiredness + 1
151       if away_team == home_teams[i - 2].Value():
152         tiredness = tiredness + 1
153       if away_team == away_teams[i - 2].Value():
154         tiredness = tiredness + 1
155  
156     print("%2d. %d vs. %d   (matchnum %2d, excitedness %d, tiredness %d)" % (i, home_team, away_team, matchnum, excitedness[matchnum], tiredness))
157   
158   print()
159   num_solutions += 1
160 solver.EndSearch()