Hi,
I’m using JuMP to pick winners of games of a single-elimination tournament. I have everything running fine except for the fact that I can’t seem to figure out how to impose a constraint that eliminated teams not be picked in future rounds.
The full code for this example with 8 teams is here, but I’ll post a small excerpt:
function SolveModelMWE(data)
N = size(data,1)
m = Model(solver=solver)
...
@variable(m, picks[1:N,1:2], Bin)
@objective(m, Max, sum(data[i,1] * sum(data[i,2+j] * picks[i,j] for j in 1:2) for i in 1:N))
@constraints m begin
....
# Constraint 2 - must have picked 7 winners, and appropriate number from each round
sum(sum(picks[i,j] for j in 1:2) for i in 1:N ) == 7
sum(sum(picks[i,j] for j in 1:2) for i in r1idx) == 4
sum(sum(picks[i,j] for j in 1:2) for i in r2idx) == 2
sum(sum(picks[i,j] for j in 1:2) for i in r3idx) == 1
# Constraint 3 - can only pick one team per game
sum(picks[:,j] for j in 1:2) .<=1
# Constraint 4 - can't pick teams eliminated in prior rounds
# ????
end
# Solve it
status = solve(m)
picked = getvalue(picks)
points = getobjectivevalue(m)
return picked,points
end
The output is
│ Row │ team1 │ team2 │ round_face │ game_number │ picked1 │ picked2 │
│ │ Int64 │ Int64 │ Int64 │ Int64 │ Bool │ Bool │
├─────┼───────┼───────┼────────────┼─────────────┼─────────┼─────────┤
│ 1 │ 7 │ 2 │ 1 │ 1 │ true │ false │
│ 2 │ 6 │ 3 │ 1 │ 2 │ false │ true │
│ 3 │ 1 │ 8 │ 1 │ 3 │ false │ true │
│ 4 │ 5 │ 4 │ 1 │ 4 │ false │ true │
│ 5 │ 7 │ 6 │ 2 │ 5 │ false │ false │
│ 6 │ 7 │ 3 │ 2 │ 5 │ false │ false │
│ 7 │ 6 │ 2 │ 2 │ 5 │ false │ false │
│ 8 │ 2 │ 3 │ 2 │ 5 │ true │ false │
│ 9 │ 1 │ 5 │ 2 │ 6 │ false │ false │
│ 10 │ 1 │ 4 │ 2 │ 6 │ false │ false │
│ 11 │ 8 │ 5 │ 2 │ 6 │ false │ false │
│ 12 │ 8 │ 4 │ 2 │ 6 │ true │ false │
│ 13 │ 7 │ 1 │ 3 │ 7 │ false │ false │
│ 14 │ 7 │ 8 │ 3 │ 7 │ false │ false │
│ 15 │ 7 │ 5 │ 3 │ 7 │ true │ false │
│ 16 │ 7 │ 4 │ 3 │ 7 │ false │ false │
│ 17 │ 6 │ 1 │ 3 │ 7 │ false │ false │
│ 18 │ 6 │ 8 │ 3 │ 7 │ false │ false │
│ 19 │ 6 │ 5 │ 3 │ 7 │ false │ false │
│ 20 │ 6 │ 4 │ 3 │ 7 │ false │ false │
│ 21 │ 2 │ 1 │ 3 │ 7 │ false │ false │
│ 22 │ 2 │ 8 │ 3 │ 7 │ false │ false │
│ 23 │ 2 │ 5 │ 3 │ 7 │ false │ false │
│ 24 │ 2 │ 4 │ 3 │ 7 │ false │ false │
│ 25 │ 3 │ 1 │ 3 │ 7 │ false │ false │
│ 26 │ 3 │ 8 │ 3 │ 7 │ false │ false │
│ 27 │ 3 │ 5 │ 3 │ 7 │ false │ false │
│ 28 │ 3 │ 4 │ 3 │ 7 │ false │ false │
and the issue is that, in game 7, the solver is picking from a match-up of team 5 and team 7 (see row 15 above), but team 5 was picked to lose in round 1 (see row 4) and team 7 was picked to win in round 1 but ignored as a participant in round 2.
I think the constraint would have to look something like
sum(picks[i,1] for i in index_of_team7_round_1) +
sum(picks[i,2] for i in index_of_team7_round_1)
.<=
sum(picks[i,1] for i in index_of_team7_round_2) +
sum(picks[i,2] for i in index_of_team7_round_2);
sum(picks[i,1] for i in index_of_team7_round_2) +
sum(picks[i,2] for i in index_of_team7_round_2)
.<=
sum(picks[i,1] for i in index_of_team7_round_3) +
sum(picks[i,2] for i in index_of_team7_round_3);
I was wondering if anyone has encountered a similar programming challenge before and has any ideas on how best to implement this? The approaches I’ve tried in the past haven’t worked.