Setting max exposure

I am trying to make lists of names given certain input parameters of performance and want to look at the variance distribution but in my code I tend to get the same names over and over as high performers. Instead what I would like to be able to do is set a maximum exposure so that out of the 20 groups that I output, I can have a single person show up in say a maximum of 10 (50% exposure), 5 (25% exposure), etc. I am relatively new to Julia so any help would be greatly appreciated!

Please provide a minimum working example or a Gist of your code. Without an idea of what your code’s actually doing, it’s hard to provide useful help.

2 Likes
using CSV 

using DataFrames

using GLPKMathProgInterface

using JuMP

#=
Variables for solving the problem
=#
# num_lineups is the total number of lineups
num_lineups = 20

# num_overlap is the maximum overlap of players between the lineups that you create
num_overlap = 4

# num_exposure is the maximum number of times a player can be in a lineup
num_exposure = 10

# path_skaters is a string that gives the path to the csv file with the skaters information
path_skaters = "C:\\Users\\engja\\Desktop\\example_skaters.csv"

# path_goalies is a string that gives the path to the csv file with the goalies information
path_goalies = "C:\\Users\\engja\\Desktop\\example_goalies.csv"

# path_to_output is a string that gives the path to the csv file that will give the outputted results
path_to_output= "C:\\Users\\engja\\Desktop\\output.csv"



# This is a function that creates one lineup using No Stacking
function one_lineup_no_stacking(skaters, goalies, lineups, num_overlap, num_skaters, num_goalies, centers, wingers, defenders, num_teams, skaters_teams, goalie_opponents, team_lines, num_lines, P1_info)
    m = Model(solver=GLPKSolverMIP())

    # Variable for skaters in lineup.
    @variable(m, skaters_lineup[i=1:num_skaters], Bin)

    # Variable for goalie in lineup.
    @variable(m, goalies_lineup[i=1:num_goalies], Bin)


    # One goalie constraint
    @constraint(m, sum(goalies_lineup[i] for i=1:num_goalies) == 1)

    # Eight Skaters constraint
    @constraint(m, sum(skaters_lineup[i] for i=1:num_skaters) == 8)

    # Between 2 and 3 centers
    @constraint(m, sum(centers[i]*skaters_lineup[i] for i=1:num_skaters) <= 3)
    @constraint(m, 2 <= sum(centers[i]*skaters_lineup[i] for i=1:num_skaters))

    # Between 3 and 4 wingers
    @constraint(m, sum(wingers[i]*skaters_lineup[i] for i=1:num_skaters) <= 4)
    @constraint(m, 3<=sum(wingers[i]*skaters_lineup[i] for i=1:num_skaters))

    # Between 2 and 3 defenders
    @constraint(m, 2 <= sum(defenders[i]*skaters_lineup[i] for i=1:num_skaters))
    @constraint(m, sum(defenders[i]*skaters_lineup[i] for i=1:num_skaters) <= 3)

    # Financial Constraint
    @constraint(m, sum(skaters[i,:Salary]*skaters_lineup[i] for i=1:num_skaters) + sum(goalies[i,:Salary]*goalies_lineup[i] for i=1:num_goalies) <= 50000)

    # At least 3 different teams for the 8 skaters constraints
    @variable(m, used_team[i=1:num_teams], Bin)
    @constraint(m, xyconstr[i=1:num_teams], used_team[i] <= sum(skaters_teams[t, i]*skaters_lineup[t] for t=1:num_skaters))
    @constraint(m, sum(used_team[i] for i=1:num_teams) >= 3)

    # Overlap Constraint
    @constraint(m, xyconstr[i=1:size(lineups)[2]], sum(lineups[j,i]*skaters_lineup[j] for j=1:num_skaters) + sum(lineups[num_skaters+j,i]*goalies_lineup[j] for j=1:num_goalies) <= num_overlap)

    # Exposure Constraint
    @constraint(m, xyconstr[i=1....]..................................................................... <= num_exposure)

    # Objective
    @objective(m, Max, sum(skaters[i,:Projection]*skaters_lineup[i] for i=1:num_skaters) + sum(goalies[i,:Projection]*goalies_lineup[i] for i=1:num_goalies))


    # Solve the integer programming problem
    println("Solving Problem...")
    @printf("\n")
    status = solve(m);


    # Puts the output of one lineup into a format that will be used later
    if status==:Optimal
        skaters_lineup_copy = Array{Int64}(0)
        for i=1:num_skaters
            if getvalue(skaters_lineup[i]) >= 0.9 && getvalue(skaters_lineup[i]) <= 1.1
                skaters_lineup_copy = vcat(skaters_lineup_copy, fill(1,1))
            else
                skaters_lineup_copy = vcat(skaters_lineup_copy, fill(0,1))
            end
        end
        for i=1:num_goalies
            if getvalue(goalies_lineup[i]) >= 0.9 && getvalue(goalies_lineup[i]) <= 1.1
                skaters_lineup_copy = vcat(skaters_lineup_copy, fill(1,1))
            else
                skaters_lineup_copy = vcat(skaters_lineup_copy, fill(0,1))
            end
        end
        return(skaters_lineup_copy)
    end
end


#=
formulation is the type of formulation that you would like to use
=#
formulation = one_lineup_No_Stacking



function create_lineups(num_lineups, num_overlap, path_skaters, path_goalies, formulation, path_to_output)


    # Load information for skaters table
    skaters = CSV.read(path_skaters)

    # Load information for goalies table
    goalies = CSV.read(path_goalies)

    # Number of skaters
    num_skaters = size(skaters)[1]

    # Number of goalies
    num_goalies = size(goalies)[1]

    # wingers stores the information on which players are wings
    wingers = Array{Int64}(0)

    # centers stores the information on which players are centers
    centers = Array{Int64}(0)

    # defenders stores the information on which players are defenders
    defenders = Array{Int64}(0)

    #=
    Process the position information in the skaters file to populate the wingers,
    centers, and defenders with the corresponding correct information
    =#
    for i =1:num_skaters
        if skaters[i,:Position] == "LW" || skaters[i,:Position] == "RW" || skaters[i,:Position] == "W"
            wingers=vcat(wingers,fill(1,1))
            centers=vcat(centers,fill(0,1))
            defenders=vcat(defenders,fill(0,1))
        elseif skaters[i,:Position] == "C"
            wingers=vcat(wingers,fill(0,1))
            centers=vcat(centers,fill(1,1))
            defenders=vcat(defenders,fill(0,1))
        elseif skaters[i,:Position] == "D" || skaters[i,:Position] == "LD" || skaters[i,:Position] == "RD"
            wingers=vcat(wingers,fill(0,1))
            centers=vcat(centers,fill(0,1))
            defenders=vcat(defenders,fill(1,1))
        else
            wingers=vcat(wingers,fill(0,1))
            centers=vcat(centers,fill(0,1))
            defenders=vcat(defenders,fill(1,1))
        end
    end


    # A forward is either a center or a winger
    forwards = centers+wingers



    # Create team indicators from the information in the skaters file
    teams = unique(skaters[:Team])

    # Total number of teams
    num_teams = size(teams)[1]

    # player_info stores information on which team each player is on
    player_info = zeros(Int, num_teams)

    # Populate player_info with the corresponding information
    for j=1:size(teams)[1]
        if skaters[1, :Team] == teams[j]
            player_info[j] =1
        end
    end
    skaters_teams = player_info'


    for i=2:num_skaters
        player_info = zeros(Int, size(teams)[1])
        for j=1:size(teams)[1]
            if skaters[i, :Team] == teams[j]
                player_info[j] =1
            end
        end
        skaters_teams = vcat(skaters_teams, player_info')
    end



    # Create goalie identifiers so you know who they are playing
    opponents = goalies[:Opponent]
    goalie_teams = goalies[:Team]
    goalie_opponents=[]
    for num = 1:size(teams)[1]
        if opponents[1] == teams[num]
            goalie_opponents = skaters_teams[:, num]
        end
    end
    for num = 2:size(opponents)[1]
        for num_2 = 1:size(teams)[1]
            if opponents[num] == teams[num_2]
                goalie_opponents = hcat(goalie_opponents, skaters_teams[:,num_2])
            end
        end
    end




    # Create line indicators so you know which players are on which lines
    L1_info = zeros(Int, num_skaters)
    L2_info = zeros(Int, num_skaters)
    L3_info = zeros(Int, num_skaters)
    L4_info = zeros(Int, num_skaters)
    for num=1:size(skaters)[1]
        if skaters[:Team][num] == teams[1]
            if skaters[:Line][num] == "1"
                L1_info[num] = 1
            elseif skaters[:Line][num] == "2"
                L2_info[num] = 1
            elseif skaters[:Line][num] == "3"
                L3_info[num] = 1
            elseif skaters[:Line][num] == "4"
                L4_info[num] = 1
            end
        end
    end
    team_lines = hcat(L1_info, L2_info, L3_info, L4_info)


    for num2 = 2:size(teams)[1]
        L1_info = zeros(Int, num_skaters)
        L2_info = zeros(Int, num_skaters)
        L3_info = zeros(Int, num_skaters)
        L4_info = zeros(Int, num_skaters)
        for num=1:size(skaters)[1]
            if skaters[:Team][num] == teams[num2]
                if skaters[:Line][num] == "1"
                    L1_info[num] = 1
                elseif skaters[:Line][num] == "2"
                    L2_info[num] = 1
                elseif skaters[:Line][num] == "3"
                    L3_info[num] = 1
                elseif skaters[:Line][num] == "4"
                    L4_info[num] = 1
                end
            end
        end
        team_lines = hcat(team_lines, L1_info, L2_info, L3_info, L4_info)
    end
    num_lines = size(team_lines)[2]




    # Create power play indicators
    PP_info = zeros(Int, num_skaters)
    for num=1:size(skaters)[1]
        if skaters[:Team][num]==teams[1]
            if skaters[:Power_Play][num] == "1"
                PP_info[num] = 1
            end
        end
    end

    P1_info = PP_info

    for num2=2:size(teams)[1]
        PP_info = zeros(Int, num_skaters)
        for num=1:size(skaters)[1]
            if skaters[:Team][num] == teams[num2]
                if skaters[:Power_Play][num] == "1"
                    PP_info[num]=1
                end
            end
        end
        P1_info = hcat(P1_info, PP_info)
    end


    # Lineups using formulation as the stacking type
    the_lineup= formulation(skaters, goalies, hcat(zeros(Int, num_skaters + num_goalies), zeros(Int, num_skaters + num_goalies)), num_overlap, num_skaters, num_goalies, centers, wingers, defenders, num_teams, skaters_teams, goalie_opponents, team_lines, num_lines, P1_info)
    the_lineup2 = formulation(skaters, goalies, hcat(the_lineup, zeros(Int, num_skaters + num_goalies)), num_overlap, num_skaters, num_goalies, centers, wingers, defenders, num_teams, skaters_teams, goalie_opponents, team_lines, num_lines, P1_info)
    tracer = hcat(the_lineup, the_lineup2)
    for i=1:(num_lineups-2)
        try
            thelineup=formulation(skaters, goalies, tracer, num_overlap, num_skaters, num_goalies, centers, wingers, defenders, num_teams, skaters_teams, goalie_opponents, team_lines, num_lines, P1_info)
            tracer = hcat(tracer,thelineup)
        catch
            break
        end
    end


    # Create the output csv file
    lineup2 = ""
    for j = 1:size(tracer)[2]
        lineup = ["" "" "" "" "" "" "" "" ""]
        for i =1:num_skaters
            if tracer[i,j] == 1
                if centers[i]==1
                    if lineup[1]==""
                        lineup[1] = string(skaters[i,1])
                    elseif lineup[2]==""
                        lineup[2] = string(skaters[i,1])
                    elseif lineup[9] ==""
                        lineup[9] = string(skaters[i,1])
                    end
                elseif wingers[i] == 1
                    if lineup[3] == ""
                        lineup[3] = string(skaters[i,1])
                    elseif lineup[4] == ""
                        lineup[4] = string(skaters[i,1])
                    elseif lineup[5] == ""
                        lineup[5] = string(skaters[i,1])
                    elseif lineup[9] == ""
                        lineup[9] = string(skaters[i,1])
                    end
                elseif defenders[i]==1
                    if lineup[6] == ""
                        lineup[6] = string(skaters[i,1])
                    elseif lineup[7] ==""
                        lineup[7] = string(skaters[i,1])
                    elseif lineup[9] == ""
                        lineup[9] = string(skaters[i,1])
                    end
                end
            end
        end
        for i =1:num_goalies
            if tracer[num_skaters+i,j] == 1
                lineup[8] = string(goalies[i,1])
            end
        end
        for name in lineup
            lineup2 = string(lineup2, name, ",")
        end
        lineup2 = chop(lineup2)
        lineup2 = string(lineup2, """

        """)
    end
    outfile = open(path_to_output, "w")
    write(outfile, lineup2)
    close(outfile)
end




# Running the code
create_lineups(num_lineups, num_overlap, path_skaters, path_goalies, formulation, path_to_output)

I pasted the code that I am trying to use. I added in a variable to control max exposure and added in a constraint, I just don’t know exactly how to structure the constraint in the body of the code.