I am trying to solve a scheduling problem related to battery output using the ompr r package which allows for mixed integer programming.Essentially, I need to find the maximum output the batteries can generate basesed on when they are activated. In my case the first row battery would be activated first and the 10th row battery would be activated last. If any subsequent batteries are activated after the previous rows' batteries and are offset another according to the Left_Battery and Right_Battery column they will be penalized (lower output). The original data might be too complex so i also added another dataset of just 3 rows for users to try and solve.
df<-structure(list(Current_Battery = 1:10, Output = c(184L, 147L,
245L, 71L, 383L, 146L, 86L, 122L, 164L, 191L), Left_Battery = c(4,
8, 7, 3, 9, 2, 6, 5, 10, 1), Right_Battery = c(9L, 8L, 4L, 7L,
10L, 1L, 2L, 3L, 6L, 5L)), class = "data.frame", row.names = c(NA,
-10L))
##function to penalize prior batteries if Left_Battery or Right_Battery is in a previous "Current_Battery" Column ##(turned on)
function2=function(vec){
df=cbind(df,vec)%>%arrange(vec)%>%select(-vec)
df=df%>%group_by(Current_Battery)%>%mutate(left_id=which(df[,1] == Left_Battery),right_id=which(df[,1] == Right_Battery))%>%ungroup()%>%mutate(self=row_number())
df=df%>%group_by(Current_Battery)%>%mutate(penalty=ifelse(self<left_id & self <right_id,1,
ifelse(self<left_id & self >right_id,.8,
ifelse(self>left_id & self >right_id,.6,
ifelse(self>left_id & self <right_id,.8,1)))))%>%
mutate(Value=penalty*Output)
final=sum(df$Value)
print(final)
}
#test 1 simply sort by highest output column
test=df%>%arrange(desc(Output))%>%select(Current_Battery)
test=test$Current_Battery
function2(test)
#test 2 random vector
rand_vec=sample(1:10)
function2(rand_vec)
##This includes a table showing an output and value for each battery
function2=function(vec){
df=cbind(df,vec)%>%arrange(vec)%>%select(-vec)
df=df%>%group_by(Current_Battery)%>%mutate(left_id=which(df[,1] == Left_Battery),right_id=which(df[,1] == Right_Battery))%>%ungroup()%>%mutate(self=row_number())
df=df%>%group_by(Current_Battery)%>%mutate(penalty=ifelse(self<left_id & self <right_id,1,
ifelse(self<left_id & self >right_id,.8,
ifelse(self>left_id & self >right_id,.6,
ifelse(self>left_id & self <right_id,.8,1)))))%>%
mutate(Value=penalty*Output)
CostPair<<-df%>%select(Current_Battery,Output,penalty,Value)
final=sum(df$Value)
print(final)
}
I've included a simpler table with 3 rows of data and example images of turning on battery 1 first 3 second and 2 last.
df=structure(list(Current_Battery = 1:3, Output = c(20, 22, 24),
Left_Battery = c(2, 3, 1), Right_Battery = c(3, 1, 2)), class = "data.frame", row.names = c(NA,
-3L))