Переставьте строки, чтобы найти максимальное значение/оптимизируйте функцию

#r #function #optimization

Вопрос:

Я пытаюсь создать функцию, которая повторяет мои данные, чтобы найти наибольшее значение. Приведенная ниже таблица содержит фрейм данных с идентификатором и доходами для каждого идентификатора. Я пытаюсь решить проблему наилучшего расположения идентификаторов, чтобы максимизировать значение npv. Одним из основных предостережений является следующий параметр. Приведенная ниже мутация определяет, находится ли какой-либо предыдущий идентификатор в пределах дельты 5. Если это так, то выручка снижается на 40%.

  df_fcn <- df_fcn %>% mutate(nearest = transform(., close_prev = random_sort[apply(`diag<-`(m <-
    as.matrix(dist(random_sort)), Inf) / upper.tri(m), 2, which.min)])) %>% as_tibble()
  
  df_fcn <- as_tibble(df_fcn$nearest)
  
  df_fcn <-
    df_fcn %>% mutate(Penalty =ifelse(id==1,1, if_else(abs(random_sort - close_prev) > 5, 1, .6)))
 
 library(zoo)
library(tidyverse)


df<-data.frame(id=c(1:500),Revenue=sample(500))

dcf <- function(x, r, t0=FALSE){
  # calculates discounted cash flows (DCF) given cash flow and discount rate
  #
  # x - cash flows vector
  # r - vector or discount rates, in decimals. Single values will be recycled
  # t0 - cash flow starts in year 0, default is FALSE, i.e. discount rate in first period is zero.
  if(length(r)==1){
    r <- rep(r, length(x))
    if(t0==TRUE){r[1]<-0}
  }
  x/cumprod(1 r)
}

npv <- function(x, r, t0=FALSE){
  # calculates net present value (NPV) given cash flow and discount rate
  #
  # x - cash flows vector
  # r - discount rate, in decimals
  # t0 - cash flow starts in year 0, default is FALSE
  sum(dcf(x, r, t0))
  
}  
  

#Only reason I created this column is to have a way of changing the row arrangment. The final function n just iterates and randomly changes the numbers to find the highest value and arrangment.

df<- df%>%mutate(random_sort= sample(nrow(df)))


schedule_function=function(i){
  df_fcn<-df%>%mutate(random_sort=sample(random_sort))
  df_fcn <- df_fcn %>% mutate(nearest = transform(., close_prev = random_sort[apply(`diag<-`(m <-
    as.matrix(dist(random_sort)), Inf) / upper.tri(m), 2, which.min)])) %>% as_tibble()
  
  df_fcn <- as_tibble(df_fcn$nearest)
  
  df_fcn <-
    df_fcn %>% mutate(Penalty =ifelse(id==1,1, if_else(abs(random_sort - close_prev) > 5, 1, .6))) %>%
    mutate(Penalty = ifelse(is.na(Penalty), 1, Penalty))
  df_fcn<- df_fcn%>%mutate(Revenue_Penalized= Revenue*Penalty)
  df_fcn<-df_fcn%>%mutate(npv=npv(df_fcn$Revenue_Penalized,.2))
  max_npv<<-npv(df_fcn$Revenue_Penalized,.2)
  final_df<<-df_fcn
    
}

schedule_function(df)


n <- 1:10000
MAX = df%>%mutate(npv=-Inf)    ## initialize maximum
for (i in 1:length(n)) {
  x <- schedule_function(df)
  if (max(x$npv) > max(MAX$npv)) MAX <- x
#unique(print(MAX$npv))  
}
 

Комментарии:

1. Возможно, это слишком упрощенная мысль, но… Почему бы просто не изменить скорректированные результаты выручки с учетом дельт в виде нового столбца, а затем использовать что-то вроде упорядочения (), а затем заголовок(1)?

2. К сожалению, я не думаю, что это может сработать. Я попытался решить эту проблему, чтобы узнать, может ли у кого-нибудь быть идея о том, как оптимизировать функцию, которая переставляет строки. Однако я могу неправильно истолковать ваш комментарий.