# Using JuMP to pick winners of a tournament

**URL:** <https://discourse.julialang.org/t/using-jump-to-pick-winners-of-a-tournament/18476>\
**Category:** Optimization (Mathematical)\
**Tags:** jump\
**Created:** [December 9, 2018, 4:16am UTC](https://discourse.julialang.org/t/using-jump-to-pick-winners-of-a-tournament/18476 "2018-12-09T04:16:58Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![tyleransom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tyleransom/32/530_2.png) [@tyleransom](https://discourse.julialang.org/u/tyleransom)\
**Post date:** [December 9, 2018, 4:16am UTC](https://discourse.julialang.org/t/using-jump-to-pick-winners-of-a-tournament/18476/1 "2018-12-09T04:16:58Z")

</div>

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](https://gist.github.com/tyleransom/3738fa6cd1b3b5602e0621b08d068380#file-mwe_constraints-jl), but I’ll post a small excerpt:

```julia
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

```julia
│ 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

```julia
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.

---

<div class="post-metadata">

**Author:** ![leethargo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leethargo/32/6004_2.png) [@leethargo](https://discourse.julialang.org/u/leethargo)\
**Post date:** [December 9, 2018, 8:50am UTC](https://discourse.julialang.org/t/using-jump-to-pick-winners-of-a-tournament/18476/2 "2018-12-09T08:50:30Z")

</div>

I did not read your whole code, or understand what you are trying to do (if the results of the individual matches are already there, isn’t the winner determined? why solve an optimization model?) but here are two suggestions:

The [Linear Ordering Problem](https://www.iwr.uni-heidelberg.de/groups/comopt/software/LOLIB/) has been used to find a ranking of a set of teams that is maximally compatible with pairwise match results.

If your `pick` variables have an index `t` for the team as well as `r` for the round, then you could ask for `pick[t,r] >= pick[t,r+1]`. That is, `t` can only be picked in round `r+1` when it was picked in `r`.

---

<div class="post-metadata">

**Author:** ![tyleransom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tyleransom/32/530_2.png) [@tyleransom](https://discourse.julialang.org/u/tyleransom)\
**Post date:** [December 9, 2018, 2:11pm UTC](https://discourse.julialang.org/t/using-jump-to-pick-winners-of-a-tournament/18476/3 "2018-12-09T14:11:48Z")

</div>

Thanks for the tips!

> [@leethargo](#):
>
> if the results of the individual matches are already there, isn’t the winner determined? why solve an optimization model?

The fact that the results are already there doesn’t make much difference to what I’m trying to do, but the idea is to simulate a bunch of different tournaments and see which team is picked the most.

> [@leethargo](#):
>
> If your `pick` variables have an index `t` for the team as well as `r` for the round, then you could ask for `pick[t,r] >= pick[t,r+1]` . That is, `t` can only be picked in round `r+1` when it was picked in `r` .

This looks like a promising avenue. Thanks for taking the time to give feedback!
