Last active
December 9, 2018 03:51
-
-
Save tyleransom/3738fa6cd1b3b5602e0621b08d068380 to your computer and use it in GitHub Desktop.
MWE for linear programming problem
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using DataFrames | |
using HTTP | |
using uCSV | |
using JuMP | |
using GLPK | |
using Cbc | |
# read in the data | |
fname = "https://gist.githubusercontent.com/tyleransom/3738fa6cd1b3b5602e0621b08d068380/raw/5c4b139639d7b3c16716289b0232b8528d1bf494/mwe.csv" | |
data = DataFrame(uCSV.read(IOBuffer(HTTP.get(fname).body), quotes='"', header=1)) | |
data = Matrix(data) | |
# id = data[:,1] | |
# val = data[:,2] | |
# score = data[:,3] | |
# id1 = data[:,4] | |
# take a subset of the data just to compare (can figure out by hand on smaller data) | |
data = data[1:14,:] | |
#solver = GLPKSolverLP() | |
solver = CbcSolver() | |
# Solve model | |
function SolveModel(data) | |
N = size(data,1) | |
m = Model(solver=solver) | |
@variable(m, is_good[1:N], Bin) | |
@variable(m, is_bad[1:N], Bin) | |
@objective(m, Max, data[i,3] * is_good[i] - data[i,3] * is_bad[i] for i in 1:N) | |
@constraints m begin | |
# Constraint 1 - sum of good vals >= sum of bad vals | |
data[i,2] * is_good[i] .>= data[i,2] * is_bad[i] | |
# Constraint 2 - can't choose the same id for both good and bad | |
is_good[1:N] .+ is_bad[1:N] .<= 1 | |
end | |
# Solve it | |
status = solve(m) | |
println(getvalue(is_good)) | |
println(getvalue(is_bad)) | |
end | |
@time SolveModel(data) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
julia> include("jump_mwe.jl") | |
ERROR: LoadError: MethodError: no method matching *(::Float64, ::Base.Generator{UnitRange{Int64},getfield(Main, Symbol("##9#10")){Array{Int64,2},Array{Variable,1},Array{Variable,1}}}) | |
Closest candidates are: | |
*(::Any, ::Any, ::Any, ::Any...) at operators.jl:502 | |
*(::Float64, ::Float64) at float.jl:399 | |
*(::AbstractFloat, ::Bool) at bool.jl:120 | |
... | |
Stacktrace: | |
[1] addtoexpr(::JuMP.GenericAffExpr{Float64,Variable}, ::Float64, ::Base.Generator{UnitRange{Int64},getfield(Main, Symbol("##9#10")){Array{Int64,2},Array{Variable,1},Array{Variable,1}}}) at /home/ransom/.julia/packages/JuMP/Xvn0n/src/parseExpr_staged.jl:289 | |
[2] macro expansion at /home/ransom/.julia/packages/JuMP/Xvn0n/src/parseExpr_staged.jl:296 [inlined] | |
[3] addtoexpr_reorder(::JuMP.GenericAffExpr{Float64,Variable}, ::Base.Generator{UnitRange{Int64},getfield(Main, Symbol("##9#10")){Array{Int64,2},Array{Variable,1},Array{Variable,1}}}) at /home/ransom/.julia/packages/JuMP/Xvn0n/src/parseExpr_staged.jl:296 | |
[4] macro expansion at /home/ransom/.julia/packages/JuMP/Xvn0n/src/macros.jl:232 [inlined] | |
[5] SolveModel(::Array{Int64,2}) at /home/ransom/jump_mwe.jl:29 | |
[6] top-level scope at util.jl:156 | |
[7] include at ./boot.jl:317 [inlined] | |
[8] include_relative(::Module, ::String) at ./loading.jl:1038 | |
[9] include(::Module, ::String) at ./sysimg.jl:29 | |
[10] include(::String) at ./client.jl:388 | |
[11] top-level scope at none:0 | |
in expression starting at /home/ransom/jump_mwe.jl:65 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
id | val | score | id1 | |
---|---|---|---|---|
1 | 9 | 0 | 64 | |
2 | 4 | 0 | 7 | |
3 | 11 | 12 | 53 | |
4 | 7 | 0 | 8 | |
5 | 4 | 35 | 11 | |
6 | 14 | 0 | 31 | |
7 | 13 | 29 | 2 | |
8 | 10 | 11 | 4 | |
9 | 2 | 18 | 18 | |
10 | 5 | 6 | 38 | |
11 | 13 | 0 | 5 | |
12 | 8 | 0 | 23 | |
13 | 15 | 0 | 44 | |
14 | 12 | 0 | 24 | |
15 | 2 | 7 | 21 | |
16 | 6 | 7 | 59 | |
17 | 9 | 0 | 32 | |
18 | 15 | 0 | 9 | |
19 | 4 | 5 | 61 | |
20 | 6 | 0 | 48 | |
21 | 15 | 0 | 15 | |
22 | 1 | 5 | 42 | |
23 | 9 | 33 | 12 | |
24 | 5 | 6 | 14 | |
25 | 15 | 0 | 39 | |
26 | 16 | 0 | 68 | |
27 | 11 | 25 | 29 | |
28 | 13 | 0 | 66 | |
29 | 6 | 0 | 27 | |
30 | 3 | 15 | 33 | |
31 | 3 | 15 | 6 | |
32 | 8 | 9 | 17 | |
33 | 14 | 0 | 30 | |
34 | 12 | 0 | 65 | |
35 | 16 | 0 | 68 | |
36 | 9 | 0 | 49 | |
37 | 7 | 0 | 55 | |
38 | 12 | 0 | 10 | |
39 | 2 | 7 | 25 | |
40 | 5 | 55 | 47 | |
41 | 10 | 0 | 46 | |
42 | 16 | 0 | 22 | |
43 | 10 | 11 | 56 | |
44 | 2 | 18 | 13 | |
45 | 16 | 0 | 62 | |
46 | 7 | 8 | 41 | |
47 | 12 | 0 | 40 | |
48 | 11 | 12 | 20 | |
49 | 8 | 9 | 36 | |
50 | 14 | 0 | 57 | |
51 | 11 | 0 | 68 | |
52 | 11 | 0 | 68 | |
53 | 6 | 0 | 3 | |
54 | 3 | 4 | 67 | |
55 | 10 | 11 | 37 | |
56 | 7 | 0 | 43 | |
57 | 3 | 9 | 50 | |
58 | 16 | 0 | 68 | |
59 | 11 | 0 | 16 | |
60 | 16 | 0 | 63 | |
61 | 13 | 0 | 19 | |
62 | 1 | 2 | 45 | |
63 | 1 | 2 | 60 | |
64 | 8 | 30 | 1 | |
65 | 5 | 6 | 34 | |
66 | 4 | 11 | 28 | |
67 | 14 | 0 | 54 | |
68 | 1 | 5 | 58 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Pwin | team1 | team2 | round_face | game_number | game_draw | game_played | underdog1 | underdog2 | potential_score1 | potential_score2 | winnerNum | loserNum | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0.219431922565201 | 7 | 2 | 1 | 1 | 0.8731271249006383 | true | true | false | 0 | 10 | 2 | 7 | |
0.428321777404977 | 6 | 3 | 1 | 2 | 0.8259745103159322 | true | true | false | 0 | 11 | 3 | 6 | |
0.855427626374035 | 1 | 8 | 1 | 3 | 0.9227457166433748 | true | false | true | 0 | 16 | 8 | 1 | |
0.593642689873469 | 5 | 4 | 1 | 4 | 0.9277263978497581 | true | true | false | 0 | 12 | 4 | 5 | |
0.392189867110385 | 7 | 6 | 2 | 5 | 0.46520655315720205 | false | true | false | 0 | 19 | 6 | 7 | |
0.323058209843327 | 7 | 3 | 2 | 5 | 0.3095865006255485 | false | true | false | 20 | 0 | 7 | 3 | |
0.314695962253744 | 6 | 2 | 2 | 5 | 0.36384712333820723 | false | true | false | 0 | 15 | 2 | 6 | |
0.61735737701594 | 2 | 3 | 2 | 5 | 0.28367704682852657 | true | false | true | 15 | 0 | 2 | 3 | |
0.735644394458733 | 1 | 5 | 2 | 6 | 0.8892309704845145 | false | false | true | 0 | 18 | 5 | 1 | |
0.805433797752599 | 1 | 4 | 2 | 6 | 0.5865761505823821 | false | false | true | 14 | 0 | 1 | 4 | |
0.331556538123172 | 8 | 5 | 2 | 6 | 0.9849133208327021 | false | true | false | 0 | 18 | 5 | 8 | |
0.421965786339032 | 8 | 4 | 2 | 6 | 0.06951775089275669 | true | true | false | 21 | 0 | 8 | 4 | |
0.125734665623416 | 7 | 1 | 3 | 7 | 0.8663918779867097 | false | true | false | 0 | 22 | 1 | 7 | |
0.470769473270697 | 7 | 8 | 3 | 7 | 0.5523356463291214 | false | false | true | 0 | 29 | 8 | 7 | |
0.303341033270792 | 7 | 5 | 3 | 7 | 0.9329328452798897 | false | true | false | 0 | 26 | 5 | 7 | |
0.392594884301928 | 7 | 4 | 3 | 7 | 0.08806065034710131 | false | true | false | 28 | 0 | 7 | 4 | |
0.201234598969552 | 6 | 1 | 3 | 7 | 0.9841275514728216 | false | true | false | 0 | 22 | 1 | 6 | |
0.578986095316038 | 6 | 8 | 3 | 7 | 0.06746086317442801 | false | false | true | 27 | 0 | 6 | 8 | |
0.410724193540738 | 6 | 5 | 3 | 7 | 0.7071320843976836 | false | true | false | 0 | 26 | 5 | 6 | |
0.502557208876912 | 6 | 4 | 3 | 7 | 0.7420025781455908 | false | true | false | 0 | 25 | 4 | 6 | |
0.365197687525855 | 2 | 1 | 3 | 7 | 0.1897901283429657 | false | true | false | 23 | 0 | 2 | 1 | |
0.755942236276598 | 2 | 8 | 3 | 7 | 0.556190992764551 | true | false | true | 23 | 0 | 2 | 8 | |
0.60658119075765 | 2 | 5 | 3 | 7 | 0.5813570879039913 | false | false | true | 23 | 0 | 2 | 5 | |
0.691194550797902 | 2 | 4 | 3 | 7 | 0.1514442293496121 | false | false | true | 23 | 0 | 2 | 4 | |
0.258806638451577 | 3 | 1 | 3 | 7 | 0.9815133430127434 | false | true | false | 0 | 22 | 1 | 3 | |
0.649098777414991 | 3 | 8 | 3 | 7 | 0.7368557023496518 | false | false | true | 0 | 29 | 8 | 3 | |
0.484683179132226 | 3 | 5 | 3 | 7 | 0.17940598906049554 | false | false | true | 24 | 0 | 3 | 5 | |
0.575687618671595 | 3 | 4 | 3 | 7 | 0.7697864650844537 | false | false | true | 0 | 25 | 4 | 3 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using DataFrames | |
using HTTP | |
using uCSV | |
using JuMP | |
using Cbc | |
solver = CbcSolver() | |
# read in the data | |
fname = "https://gist.githubusercontent.com/tyleransom/3738fa6cd1b3b5602e0621b08d068380/raw/1664e3d0d5cb8973ab5eb23fa406667ab4b7e9ca/mwe_all.csv" | |
mwe = DataFrame(uCSV.read(IOBuffer(HTTP.get(fname).body), quotes='"', header=1)) | |
mwe[:game_played] = convert(Array{Bool},mwe[:game_played].=="true") | |
mwe[:underdog1] = convert(Array{Bool},mwe[:underdog1].=="true") | |
mwe[:underdog2] = convert(Array{Bool},mwe[:underdog2].=="true") | |
function SolveModelMWE(data) | |
N = size(data,1) | |
m = Model(solver=solver) | |
r1idx = findall(data[:,2].==1) | |
r2idx = findall(data[:,2].==2) | |
r3idx = findall(data[:,2].==3) | |
r1u1idx = findall((data[:,7].==1) .& (data[:,2].==1)) | |
r1u2idx = findall((data[:,8].==1) .& (data[:,2].==1)) | |
r2u1idx = findall((data[:,7].==1) .& (data[:,2].==2)) | |
r2u2idx = findall((data[:,8].==1) .& (data[:,2].==2)) | |
r3u1idx = findall((data[:,7].==1) .& (data[:,2].==3)) | |
r3u2idx = findall((data[:,8].==1) .& (data[:,2].==3)) | |
gnums = [findall(data[:,9].==j) for j=1:7] | |
@variable(m, picks[1:N,1:2], Bin) | |
# data matrix: game_played, round_face, points1, points2, team1, team2, underdog1, underdog2, game_number | |
@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 1 - must pick sufficient number of lower-ranked teams | |
sum(picks[i,1] for i in r1u1idx) + sum(picks[i,2] for i in r1u2idx) >= 2 | |
sum(picks[i,1] for i in r2u1idx) + sum(picks[i,2] for i in r2u2idx) >= 1 | |
sum(picks[i,1] for i in r3u1idx) + sum(picks[i,2] for i in r3u2idx) >= 1 | |
# 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 | |
# ???? | |
# Constraint 5 - can't pick more than one game per set of potential matchups in a given round | |
sum(sum(picks[i,j] for j in 1:2) for i in gnums[1 ]) == 1 | |
sum(sum(picks[i,j] for j in 1:2) for i in gnums[2 ]) == 1 | |
sum(sum(picks[i,j] for j in 1:2) for i in gnums[3 ]) == 1 | |
sum(sum(picks[i,j] for j in 1:2) for i in gnums[4 ]) == 1 | |
sum(sum(picks[i,j] for j in 1:2) for i in gnums[5 ]) == 1 | |
sum(sum(picks[i,j] for j in 1:2) for i in gnums[6 ]) == 1 | |
sum(sum(picks[i,j] for j in 1:2) for i in gnums[7 ]) == 1 | |
end | |
# Solve it | |
status = solve(m) | |
picked = getvalue(picks) | |
points = getobjectivevalue(m) | |
return picked,points | |
end | |
picked_test,points_test = SolveModelMWE(Matrix(mwe[:,[:game_played,:round_face,:potential_score1,:potential_score2,:team1,:team2,:underdog1,:underdog2,:game_number]])) | |
mwe[:picked1] = picked_test[:,1].==1 | |
mwe[:picked2] = picked_test[:,2].==1 | |
println(mwe[:,[:team1,:team2,:round_face,:game_number,:winnerNum,:loserNum,:picked1,:picked2]]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment