首页 > 解决方案 > 从 excel 到 R 的非线性优化

问题描述

问题:为每种产品找到最佳折扣,以充分利用支出预算。简单来说,我需要通过以下约束更改折扣来最大化销售额:

使用的公式(差异变量之间的关系):(详细共享,在本节末尾,我使用 excel 解决问题。)

完成的工作:凭借对优化的幼稚知识,以及极端的谷歌搜索/检查各种 SO 帖子,我设法在这里找到了一些与我的问题相关的帖子,其中建议使用NlcOptim::solnl。和代码如下:

输入数据

structure(list(product = c("A", "B", "C", "D", "E", "F", "G", 
"H", "I", "J", "K", "L", "M", "N"), mrp = c(159, 180, 180, 230, 
230, 500, 500, 310, 288, 310, 500, 425, 425, 465), discount_coef = c(0.301594884229324, 
0.614829352312733, 0.149146787052132, 0.248723558155458, 0.138769169527518, 
0.330703149210594, 0.335917219291645, 0.296582160231912, 0.357483743973616, 
0.24978922074796, 0.334178652809571, 0.292011550773066, 0.157611497322651, 
0.357562105368776), min_discount = c(14.31, 25.2, 25.2, 29.9, 
29.9, 100, 100, 71.3, 66.24, 71.3, 100, 51, 51, 51.15), max_discount = c(39.75, 
30.6, 30.6, 39.1, 39.1, 200, 200, 179.8, 155.52, 179.8, 200, 
174.25, 174.25, 190.65)), row.names = c(NA, 14L), class = "data.frame") -> optim_data

代码

library("NlcOptim")

(coeff <- optim_data$discount_coef)
#>  [1] 0.3015949 0.6148294 0.1491468 0.2487236 0.1387692 0.3307031 0.3359172
#>  [8] 0.2965822 0.3574837 0.2497892 0.3341787 0.2920116 0.1576115 0.3575621
(min_discount <- optim_data$min_discount)
#>  [1]  14.31  25.20  25.20  29.90  29.90 100.00 100.00  71.30  66.24  71.30
#> [11] 100.00  51.00  51.00  51.15
(max_discount <- optim_data$max_discount)
#>  [1]  39.75  30.60  30.60  39.10  39.10 200.00 200.00 179.80 155.52 179.80
#> [11] 200.00 174.25 174.25 190.65
(mrp <- optim_data$mrp)
#>  [1] 159 180 180 230 230 500 500 310 288 310 500 425 425 465
(discount <- numeric(length = 14L))
#>  [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0

## objective function
obj <- function(discount) {
  sales_value <- (discount/mrp) * coeff
  return(sum(sales_value))
}

## constraint
con <- function(discount) {
  sales <- (discount/mrp)*coeff
  spend <- (sales/(mrp-discount))*discount
  f = NULL
  f = rbind(f, sum(spend)-100) # 100 is spend budget
  return(list(ceq = f, c = NULL))
}

## optimize 
result <- solnl(X = discount, objfun = obj, confun = con, 
                lb = min_discount, ub = max_discount)
#> Error in solnl(X = discount, objfun = obj, confun = con, lb = min_discount, : object 'lambda' not found

reprex 包(v0.3.0)于 2020-07-03 创建

问题:

  1. 它不断抛出错误消息“找不到对象'lambda'”,我对如何解决这个问题一无所知。
  2. 如何解决 R 中共享的非线性优化问题?有没有其他方法可以解决问题??

详细信息:Excel解决方案

在此处输入图像描述

在此处输入图像描述

标签: rmathematical-optimizationexcel-solver

解决方案


这找到与 Xl Solver 相同的结果:

optim_data$constant <- c(30,60,-10,34,-23,54,-34,-56,23,45,-71,19,29,39)

obj <- function(discount) {
  sales_value <- (discount * optim_data$discount_coef) + optim_data$constant
  return(-sum(sales_value)) # looking for minimum
}

con <- function(discount) {
  sales_value <- (discount * optim_data$discount_coef) + optim_data$constant
  spend_value = (sales_value/(optim_data$mrp-discount))*discount
  return(list(ceq = NULL, c = sum(spend_value)-100))
}

library(NlcOptim)
solnl(X= optim_data$min_discount, objfun = obj, confun  =con , lb = optim_data$min_discount , ub = optim_data$max_discount )
#> $par
#>            [,1]
#>  [1,]  14.31000
#>  [2,]  25.20000
#>  [3,]  30.60000
#>  [4,]  29.90000
#>  [5,]  39.10000
#>  [6,] 100.00000
#>  [7,] 164.95480
#>  [8,] 164.56988
#>  [9,]  66.24000
#> [10,]  71.30000
#> [11,] 200.00000
#> [12,]  82.55170
#> [13,]  51.00000
#> [14,]  77.33407
#> 
#> $fn
#> [1] -481.6475

请注意,目标函数应该是负的,因为solnl它正在寻找最小值。
约束应该是c而不是ceq因为它是一个不等式:spend-100<0


推荐阅读