0

The goal: Use current lpSolve code to create a new code using the lpSolveAPI package.

The background: I have been using lpSolve to find an optimal solution, for purposes of creating fantasy sports contest lineups, which maximizes the projected points (DK) of the players on the team versus the maximum allowed total salary (SALARY) - with a handful of other constraints to fit the rules of the contest. I have discovered in a few instances, however, lpSolve fails to find the most optimal solution. It seemingly overlooks the best points/dollar solution for some unknown reason and finds only the nth best solution instead. Unfortunately, I do not have an example of this as I had issues with my archive drive recently and lost quite a bit of data.

My research/ask: I have read other threads here that have had similar issues with lpSolve (like this one here). In those instances, lpSolveAPI was able to see the optimal solution when lpSolve could not. Not being familiar with lpSolveAPI, I am looking for assistance from someone familiar with both packages in converting my current code to instead take advantage of the lpSolveAPI package and eliminate lpSolve oversight going forward. I have tried but, for some reason, I keep getting lost in the translation.

My lpSolve code:

# count the number of unique teams and players
unique_teams = unique(slate_players$TEAM)
unique_players = unique(slate_players$PLAYERID)

# define the objective for the solver
obj = slate_players$DK

# create a constraint matrix for the solver
con = rbind(t(model.matrix(~ POS + 0, slate_players)), #Positions
            t(model.matrix(~ PLAYERID + 0, slate_players)), #DupPlayers
            t(model.matrix(~ TEAM + 0, slate_players)), #SameTeam
            rep(1,nrow(slate_players)), #TotPlayers
            slate_players$SALARY) #MaxSalary

# set the direction for each of the constraints
dir = c("==", #1B
        "==", #2B
        "==", #3B
        "==", #C
        "==", #OF
        "==", #SP
        "==", #SS
        rep('<=',length(unique_players)), #DupPlayers
        rep('<=',length(unique_teams)), #SameTeam
        "==", #TotPlayers
        "<=") #MaxSalary

# set the limits for the right-hand side of the constraints
rhs = c(1, #1B
        1, #2B
        1, #3B
        1, #C
        3, #OF
        2, #SP
        1, #SS
        rep(1,length(unique_players)), #DupPlayers
        rep(5,length(unique_teams)), #SameTeam
        10, #TotPlayers
        50000) #MaxSalary

# find the optimal solution using the solver
result = lp("max", obj, con, dir, rhs, all.bin = TRUE)

# create a data frame for the players in the optimal solution
solindex = which(result$solution==1)
optsolution = slate_players[solindex,]

Thank you for your help!

Eric_Alan
  • 115
  • 7

1 Answers1

2

This should be straightforward:

library(lpSolveAPI)
ncons <- nrow(con)
nvars <- length(obj)
lprec <- make.lp(nrow=ncons, ncol=ncols)
set.objfn(lprec, obj)
set.type(lprec, 1:nvars, "binary") # all.bin=TRUE
for (i in 1:ncons) {
    set.row(lprec, row=i, xt=con[i,])
    set.constr.type(lprec, dir[i], constraints=i)
    set.rhs(lprec, b=rhs[i], constraints=i)
}
status <- solve(lprec)
if(status!=0) stop("no solution found, error code=", status)
sol <- get.variables(lprec)

This code is untested since your question has missing data references and no expected solution.

Karsten W.
  • 17,826
  • 11
  • 69
  • 103