使用R语言nloptr包求解非线性优化问题结果异常求助
烘焙店生产规划优化问题修正
问题背景
店内售卖三款烘焙产品,参数如下:
- Apple Pie(苹果派):单份利润12美元,生产需30分钟工时、3个鸡蛋
- Croissant(可颂):单份利润8美元,生产需15分钟工时、2个鸡蛋
- Donut(甜甜圈):单份利润5美元,生产需10分钟工时、1个鸡蛋
约束条件:
- 总可用工时:500分钟
- 总可用鸡蛋:60个
- 所有产品产量≥0
核心目标:最大化总利润
原代码问题分析
运行原代码得到(0,0,0)的不合理结果,原因有两点:
- 目标函数方向错误:
nloptr默认执行最小化目标函数,但我们需要最大化利润。原代码直接返回总利润,相当于让算法寻找利润最小的解,自然会得到全0的结果。 - 初始值与算法适配性问题:原代码从(0,0,0)开始迭代,加上算法特性,容易陷入局部最优解;同时该问题是标准线性规划问题,用非线性全局优化算法效率低且易出错。
修正方案
方案1:调整nloptr代码适配最大化需求
将目标函数改为返回负利润,把最大化问题转化为最小化问题;同时调整初始值、增加迭代次数,避免陷入局部最优:
library(nloptr) # 目标函数:返回负利润,将最大化问题转为最小化问题 objective <- function(x) { profit <- c(12, 8, 5) # 三款产品的单份利润 total_profit <- sum(profit * x) return(-total_profit) # 取负数,最小化负利润等价于最大化利润 } # 约束函数:返回值需满足 ≥0,代表资源未超支 constraint <- function(x) { labor_mins <- c(30, 15, 10) # 各产品工时消耗 eggs <- c(3, 2, 1) # 各产品鸡蛋消耗 labor_constraint <- 500 - sum(labor_mins * x) # 剩余工时≥0 egg_constraint <- 60 - sum(eggs * x) # 剩余鸡蛋≥0 return(c(labor_constraint, egg_constraint)) } # 优化选项:增加迭代次数,避免过早收敛 opts <- list( "algorithm" = "NLOPT_GN_ISRES", "xtol_rel" = 1e-8, "maxeval" = 10000 ) # 定义优化问题:设置非零初始值,避免从全0开始 res <- nloptr( x0 = c(5, 10, 15), eval_f = objective, lb = rep(0, 3), # 产量非负约束 ub = rep(Inf, 3), eval_g_ineq = constraint, opts = opts ) # 输出结果 print(res) cat("最优总利润:", -res$objective, "美元\n") cat("最优产量:苹果派", round(res$solution[1]), "个,可颂", round(res$solution[2]), "个,甜甜圈", round(res$solution[3]), "个\n")
方案2:改用线性规划专用工具(更高效准确)
该问题是标准线性规划(LP)问题,使用lpSolve包可以直接处理最大化需求,还能轻松设置整数产量约束(符合实际生产场景):
library(lpSolve) # 目标系数:各产品单份利润(目标是最大化) obj <- c(12, 8, 5) # 约束矩阵:每行对应一个约束,每列对应一款产品 const_mat <- matrix( c(30, 15, 10, # 工时约束:总消耗≤500分钟 3, 2, 1), # 鸡蛋约束:总消耗≤60个 nrow = 2, byrow = TRUE ) # 约束方向:≤ const_dir <- c("<=", "<=") # 约束右端值:资源总量 const_rhs <- c(500, 60) # 求解线性规划,设置all.int=TRUE保证产量为整数 res <- lp("max", obj, const_mat, const_dir, const_rhs, all.int = TRUE) # 输出结果 print(res) cat("最优总利润:", res$objval, "美元\n") cat("最优产量:苹果派", res$solution[1], "个,可颂", res$solution[2], "个,甜甜圈", res$solution[3], "个\n")
运行方案2的代码会得到合理的最优解:生产20个可颂和20个甜甜圈,总利润260美元,完全符合资源约束。
内容的提问来源于stack exchange,提问作者Yang-Chun Lin
相关产品推荐
相关产品推荐

