基于R语言lpSolve的线性优化:15美元预算下最大化卡路里
15美元预算下最大化卡路里的线性规划求解(带约束扩展)
原代码的核心问题
- 约束矩阵维度错误:
lpSolve要求约束矩阵每行对应一个约束,你原代码中price是列向量,需转置为行向量才能被正确识别。 - 未指定整数变量:商品购买数量必须是整数,需添加
int.vec参数声明所有变量为整数,否则会得到无实际意义的非整数解。
基础版:仅预算约束下的最大卡路里求解
以下是修正后的基础代码,解决15美元预算内最大化卡路里的问题:
library(lpSolve) # 10种商品的卡路里与价格数据 cals <- c(830, 110, 600, 710, 210, 70, 200, 380, 460, 634) price <- c(7.89, 9.96, 11.31, 7.87, 7.04, 7.18, 4.43, 9.10, 6.72, 6.20) # 目标函数:最大化总卡路里,系数为各商品卡路里值 objective.in <- cals # 约束矩阵:每行一个约束,第一行为预算约束(价格总和 ≤15) const.mat <- t(as.matrix(price)) # 约束方向 const.dir <- "<=" # 约束阈值:预算上限15美元 const.rhs <- 15 # 求解:指定所有变量为整数 opt <- lp( direction = "max", objective.in = objective.in, const.mat = const.mat, const.dir = const.dir, const.rhs = const.rhs, int.vec = 1:length(cals) ) # 输出结果 cat("最大卡路里值:", opt$objval, "\n") cat("各商品购买数量:", opt$solution, "\n")
扩展约束1:至少购买x件商品
比如要求至少买2件,只需新增“变量总和 ≥x”的约束:
# 扩展约束矩阵:预算约束 + 购买数量总和约束 const.mat <- rbind( t(as.matrix(price)), # 原预算约束 rep(1, length(cals)) # 新约束:所有商品购买数量之和 ≥2 ) # 约束方向:预算≤,数量总和≥ const.dir <- c("<=", ">=") # 约束阈值:预算15,至少买2件 const.rhs <- c(15, 2) # 求解 opt <- lp( direction = "max", objective.in = objective.in, const.mat = const.mat, const.dir = const.dir, const.rhs = const.rhs, int.vec = 1:length(cals) )
扩展约束2:限制每件商品购买数量
情况A:每件最多买2件(可买0件)
给每个商品添加“购买数量 ≤2”的约束:
# 约束矩阵:预算约束 + 10个商品的数量上限约束 const.mat <- rbind( t(as.matrix(price)), # 预算约束 diag(length(cals)) # 对角矩阵,每行对应一个商品的数量上限(≤2) ) # 约束方向:预算≤,10个商品≤2 const.dir <- c("<=", rep("<=", length(cals))) # 约束阈值:预算15,每个商品最多买2件 const.rhs <- c(15, rep(2, length(cals))) # 求解 opt <- lp( direction = "max", objective.in = objective.in, const.mat = const.mat, const.dir = const.dir, const.rhs = const.rhs, int.vec = 1:length(cals) )
情况B:每件必须买1或2件(不可买0件)
给每个商品添加“购买数量 ≥1”和“购买数量 ≤2”的双重约束:
# 约束矩阵:预算约束 + 10个≥1约束 + 10个≤2约束 const.mat <- rbind( t(as.matrix(price)), # 预算约束 diag(length(cals)), # 每个商品≥1的约束 diag(length(cals)) # 每个商品≤2的约束 ) # 约束方向:预算≤,10个≥,10个≤ const.dir <- c("<=", rep(">=", length(cals)), rep("<=", length(cals))) # 约束阈值:预算15,每个商品至少买1件、最多买2件 const.rhs <- c(15, rep(1, length(cals)), rep(2, length(cals))) # 求解 opt <- lp( direction = "max", objective.in = objective.in, const.mat = const.mat, const.dir = const.dir, const.rhs = const.rhs, int.vec = 1:length(cals) )
内容的提问来源于stack exchange,提问作者codeweird
相关产品推荐
相关产品推荐

