0

I have a function that calculates the total value given a vector of unique integer numbers. For example, in the problem below i would like to find the maximum value by changing the vector numbers. Constraints are that the vector must be a length of 8 and between 1:8. ie c(1,2,3,4,5,6,7,8) or it could be c(5,2,8,1,4,7,3,6) AND numbers cannot repeat themselves. Below is some data and the function

library(tidyverse)
####Create fake data and do some munging

light<- c("a","d","d","e","e","c","b","f","f","h","h","i")
offset_light<-c("d","a","e","d","c","e","f","b","h","f","i","h")
power<-sample(5:10,8,replace=T)  
  
light_power_tble<- data.frame(unique(light),power)

neighbor_table<-data.frame(light,offset_light)
neighbor_table<-neighbor_table%>%group_by(light)%>%mutate(NumOffset=row_number())
neighbor_table<-neighbor_table%>%pivot_wider(names_from=NumOffset,names_glue = "{.value}_{NumOffset}",values_from = offset_light)

Function to find the value given a vector of length 8 with no repeating values

max_value_function<-function(i_vector){
light_power_tbl_prep<-light_power_tble%>%mutate(starting_period=i_vector)%>%
  arrange(starting_period)%>%left_join(neighbor_table,by=c("unique.light."="light"))


#######Data processing to get final output
period_start_tbl<-light_power_tbl_prep%>%select(unique.light.,starting_period)

light_power_tbl_prep<-left_join(light_power_tbl_prep,period_start_tbl,by=c("offset_light_1"="unique.light."))%>%
  rename(offset_1_starting_period=starting_period.y)

light_power_tbl_prep<-left_join(light_power_tbl_prep,period_start_tbl,by=c("offset_light_2"="unique.light."))%>%
  rename(offset_2_starting_period=starting_period,starting_period=starting_period.x)
light_power_tbl_prep<-light_power_tbl_prep%>%mutate(offset_1_starting_period=replace_na(offset_1_starting_period,100),
                                                    offset_2_starting_period=replace_na(offset_2_starting_period,100))

##########################
##Penalizing Power value if offset_1_starting_period offset_2_starting_period is less than starting period
light_power_tbl_prep%>%group_by(unique.light.)%>%
  mutate(Output_Penalty=ifelse(starting_period>offset_1_starting_period & starting_period>offset_2_starting_period,.4,
                               ifelse(starting_period>offset_1_starting_period & starting_period<offset_2_starting_period,.6,
                                      ifelse(starting_period<offset_1_starting_period & starting_period>offset_2_starting_period,.6,1))))%>%
  mutate(Final_Output=Output_Penalty*power)%>%ungroup()%>%
  summarise(Final_Output=sum(Final_Output))

}


##I just made this up: This is what i would like to optimize on. 
vec=c(2,1,4,6,5,8,3,7)

max_value_function(vec)

Just to clarify the placement of the numbers within the vector matters. Is there a package that can optimize on this function? Also, randomly sampling would not work as my actual data is quite large.

thanks!

jsimpsno
  • 448
  • 4
  • 19

1 Answers1

0

IIUC, possible solutions are the permutations of the numbers 1 to 8, i.e. you have 40320 possible solutions. If your objective function is reasonably fast, you could run a loop over all possible solutions and keep the best one.

Enrico Schumann
  • 1,278
  • 7
  • 8