You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于R(solver)的预算优化:固定Ges值下实现预算最小化

固定Ges值下的预算最小化解决方案

要实现「固定Ges值(比如70)同时最小化总预算」的需求,本质是带非线性等式约束的优化问题——我们的目标从「最大化Ges」转为「最小化总预算」,同时新增约束条件「NrwGes(Budget) = 目标值」,还要保证每个渠道的预算非负。

下面是具体的实现步骤和代码:

1. 优化原NrwGes函数(增强灵活性)

我把原函数里硬编码的参数(Speed、maxnrw、cpcrp)改成可传入的参数,避免函数内部的固定值,方便后续调整:

NrwGes <- function(Budget, Speed, maxnrw, cpcrp) {
  # 计算各渠道的曝光量(Budget单位转千后除以cpcrp)
  exposures <- Budget * 1000 / cpcrp
  
  # 封装单个渠道的贡献计算逻辑,减少重复代码
  calc_contribution <- function(exp, speed, max_nrw, scale) {
    exp^speed / (1 + abs(exp^speed - 1)/(max_nrw * scale))
  }
  
  # 计算每个渠道的转化贡献
  a <- calc_contribution(exposures[1], Speed[1], maxnrw[1], 0.98)
  b <- calc_contribution(exposures[2], Speed[2], maxnrw[2], 0.98)
  c <- calc_contribution(exposures[3], Speed[3], maxnrw[3], 0.98)
  d <- calc_contribution(exposures[4], Speed[4], maxnrw[4], 0.98)
  e <- calc_contribution(exposures[5], Speed[5], maxnrw[5], 0.93)
  
  # 按漏斗逻辑计算总Ges值
  Ges <- a + 
         (100 - a)/100 * b + 
         (100 - a)/100 * (100 - b)/100 * c + 
         (100 - a)/100 * (100 - b)/100 * (100 - c)/100 * d + 
         (100 - a)/100 * (100 - b)/100 * (100 - c)/100 * (100 - d)/100 * e
  return(Ges)
}

2. 定义优化目标与约束

  • 目标函数:我们要最小化总预算,所以直接返回预算向量的总和
  • 等式约束:要求NrwGes的计算结果等于目标值(这里设为70)
  • 边界约束:每个渠道的预算不能为负数
# 目标函数:最小化总预算
obj_fun <- function(Budget) {
  sum(Budget)
}

# 等式约束函数:返回Ges值与目标值的差值(要求差值为0)
eq_constraint <- function(Budget) {
  NrwGes(Budget, 
         Speed = c(0.9, 0.9, 0.9, 0.9, 0.9), 
         maxnrw = c(90, 40, 40, 25, 15), 
         cpcrp = c(6564, 4494, 3962, 4525, 4900)) - 70  # 此处修改目标Ges值
}

3. 使用nloptr执行优化

R自带的optim对非线性约束支持有限,我们用nloptr包(专门处理非线性优化问题的工具),它能直接处理等式约束和边界约束。

# 安装并加载nloptr包(未安装则执行安装)
if (!require(nloptr)) install.packages("nloptr")
library(nloptr)

# 设置初始预算(沿用原问题的总预算5000分配逻辑)
initial_budget <- 5000 * rep(1, 5) / sum(rep(1, 5))

# 优化配置:选择适合非线性约束的COBYLA算法,设置精度和迭代次数
opts <- list(
  "algorithm" = "NLOPT_LN_COBYLA",
  "xtol_rel" = 1e-6,  # 精度阈值
  "maxeval" = 10000,  # 最大迭代次数
  "print_level" = 3   # 打印优化过程,设为0可关闭
)

# 运行优化
result <- nloptr(
  x0 = initial_budget,       # 初始值
  eval_f = obj_fun,          # 目标函数
  eval_g_eq = eq_constraint, # 等式约束
  lb = rep(0, 5),            # 预算下限(每个渠道≥0)
  opts = opts
)

4. 查看优化结果

运行完后可以提取最优解并验证:

# 打印完整优化结果
print(result)

# 提取最优预算分配
optimal_budget <- result$solution
cat("最优渠道预算分配:", round(optimal_budget, 2), "\n")
cat("最小总预算:", round(sum(optimal_budget), 2), "\n")
cat("验证Ges值:", round(NrwGes(optimal_budget, 
                               Speed = c(0.9, 0.9, 0.9, 0.9, 0.9), 
                               maxnrw = c(90, 40, 40, 25, 15), 
                               cpcrp = c(6564, 4494, 3962, 4525, 4900)), 2), "\n")

关键说明

  • 若需调整目标Ges值,直接修改eq_constraint函数里的70即可
  • COBYLA是无导数优化算法,适合这类目标/约束函数不可导的场景
  • 初始预算的选择会影响优化效率,如果初始值离最优解太远,可适当增加迭代次数

内容的提问来源于stack exchange,提问作者user7353167

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:49:58