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

基于R的预算分配优化(替代Excel Solver):最大化Gesamt值求解

在R中解决固定预算约束下的预算分配优化问题

嘿,你已经把Excel里的预算分配问题搬到R里了,目标很明确:在固定总预算限制下,给BudgetA到BudgetE分配金额,最大化NrwGes函数返回的"Gesamt"值。我先帮你补全并整理函数逻辑,再带你实现整个优化流程。

第一步:完善你的NrwGes函数

从你给出的片段来看,函数是通过各渠道预算计算对应的NRW值,再应用速度系数和最大NRW限制,最后求和得到总"Gesamt"。我把截断的部分补全(如果逻辑和你的实际需求有出入,你可以直接修改计算环节):

NrwGes <- function(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)) {
  # 拆分预算向量到各渠道
  BudgetA <- Budget[1]
  BudgetB <- Budget[2]
  BudgetC <- Budget[3]
  BudgetD <- Budget[4]
  BudgetE <- Budget[5]
  
  # 计算各渠道的基础NRW(预算转成对应量,单位转换用*1000)
  TV <- BudgetA * 1000 / cpcrp[1]
  Catchup <- BudgetB * 1000 / cpcrp[2]
  Social <- BudgetC * 1000 / cpcrp[3]
  Display <- BudgetD * 1000 / cpcrp[4]
  Search <- BudgetE * 1000 / cpcrp[5]
  
  # 应用速度系数和最大NRW限制,取两者较小值
  TV_nrw <- pmin(TV * Speed[1], MaxNRW[1])
  Catchup_nrw <- pmin(Catchup * Speed[2], MaxNRW[2])
  Social_nrw <- pmin(Social * Speed[3], MaxNRW[3])
  Display_nrw <- pmin(Display * Speed[4], MaxNRW[4])
  Search_nrw <- pmin(Search * Speed[5], MaxNRW[5])
  
  # 计算总Gesamt值
  Gesamt <- sum(TV_nrw, Catchup_nrw, Social_nrw, Display_nrw, Search_nrw)
  
  # 返回总结果和各渠道明细,方便后续验证
  return(list(Gesamt = Gesamt, 
              Channel_NRW = c(TV = TV_nrw, Catchup = Catchup_nrw, 
                              Social = Social_nrw, Display = Display_nrw, 
                              Search = Search_nrw)))
}

第二步:构建优化目标函数

R里的大多数优化工具默认是最小化目标函数,所以我们把最大化"Gesamt"转化为最小化它的负值:

# 目标函数:输入预算向量,返回负的Gesamt值(用于最小化)
objective_fun <- function(Budget) {
  nrw_result <- NrwGes(Budget)
  return(-nrw_result$Gesamt)
}

第三步:设置约束条件

假设你的固定总预算是total_budget(比如50000,替换成你的实际值),约束包括:

  • 所有渠道预算之和等于总预算
  • 每个渠道的预算不能为负数(不能分配负金额)

我们用基础R自带的constrOptim函数来处理约束优化,先整理约束的矩阵和向量:

# 替换成你的实际固定总预算
total_budget <- 50000

# 初始值:先平均分配预算给5个渠道,作为优化的起点
initial_budget <- rep(total_budget / 5, 5)

# 构建约束条件(constrOptim要求格式为 ui %*% Budget <= ci)
# 1. 预算总和 <= total_budget → 1*BudgetA +1*BudgetB +...+1*BudgetE <= total_budget
# 2. 预算总和 >= total_budget → -1*BudgetA -1*BudgetB -...-1*BudgetE <= -total_budget
# 3. 每个渠道预算 >=0 → -BudgetA <=0, -BudgetB <=0, ..., -BudgetE <=0
ui <- rbind(rep(1, 5),       # 约束1
            rep(-1, 5),      # 约束2
            diag(-1, 5))     # 约束3(5个不等式)
ci <- c(total_budget,        # 约束1的上限
        -total_budget,       # 约束2的上限
        rep(0, 5))           # 约束3的上限

第四步:运行优化并查看结果

现在可以执行优化了,constrOptim会帮我们找到满足约束的最优预算分配:

# 运行约束优化,不用手动提供梯度,用数值梯度计算
optim_result <- constrOptim(theta = initial_budget, 
                            f = objective_fun,
                            grad = NULL,
                            ui = ui, 
                            ci = ci)

# 输出最优分配结果
cat("最优预算分配(BudgetA到BudgetE):\n")
print(round(optim_result$par, 2))  # 保留两位小数更直观

# 输出最大化后的Gesamt值
cat("\n最大化的总Gesamt值:\n")
print(-optim_result$value)

额外说明

  • 如果你的NrwGes函数逻辑和我补全的不一样,只需要修改函数内部的计算部分,优化框架是通用的。
  • 每个渠道的最大NRW限制已经在NrwGes里用pmin处理了,所以优化时不需要额外加这层约束。
  • 如果你需要更高效的优化(比如处理更复杂的函数),可以试试nloptr包,它支持更多专业的优化算法(比如SQP)。

内容的提问来源于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 03:54:50