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

R语言线性规划优化结果异常:最优解全为0的原因排查

使用lpSolveAPI求解线性规划得到全0解的原因及修正方案

问题背景

在R中使用lpSolveAPI包求解作物种植利润最大化的线性规划问题时,预期最优解为作物A生产10蒲式耳、作物B生产15蒲式耳,但实际运行代码后得到的决策变量值全为0。

原代码

install.packages("stats")
install.packages("RMySQL")
install.packages("lpSolveAPI")
library(lpSolveAPI)
library(readr)
library(tidyverse)
library(lubridate)
library(RMySQL)


# Decision variables:
x = number of bushels A
y = number of bushels B

# Constraints:
x + 2*y ≤ 50 (Land)
2*x + 3*y ≤ 75 (Water)
3*x + 2*y ≤ 60 (Fertilizer)
x + 2*y ≤ 40  (Labor)

# Objective Function:
# Maximize profits 

lp_crop <- make.lp(0,2)
set.objfn(lp_crop, c(20, 30))
add.constraint(lp_crop, c(1, 2), "<=", 50)
add.constraint(lp_crop, c(2, 3), "<=", 75)
add.constraint(lp_crop, c(3, 2), "<=", 60)
add.constraint(lp_crop, c(1, 2), "<=", 40)

invisible(lp.control(lp_crop, sense = 'max'))
print(lp_crop)

solve(lp_crop)

# optimal amount of bushels to produce for each crop

v <- get.variables(lp_crop)
paste0('# A bushels', v[1])
paste0('# B bushels', v[2])

预期结果

## [1] "# A bushels 10"
## [1] "# B bushels 15"

实际结果

paste0('# B bushels', v[2])
# [1] "# B bushels0"
paste0('# A bushels', v[1])
# [1] "# A bushels0"
paste0('# B bushels', v[2])
# [1] "# B bushels0"

问题原因

核心问题是未添加决策变量的非负约束。线性规划中,作物种植数量不可能为负数,但lpSolveAPI默认不会自动为决策变量设置x ≥ 0、y ≥ 0的约束条件。当缺少该约束时,求解器会考虑负数解,但由于目标是最大化利润(决策变量系数为正),负数解会导致利润降低,最终求解器只能返回0作为可行解。

另外,invisible(lp.control(lp_crop, sense = 'max'))的写法虽能设置最大化目标,但并非导致解为0的直接原因。

修正后的代码

install.packages("lpSolveAPI")
library(lpSolveAPI)

# 创建LP模型,指定2个决策变量
lp_crop <- make.lp(0, 2)
# 设置目标为最大化
lp.control(lp_crop, sense = "max")

# 设置目标函数系数(作物A利润20,作物B利润30)
set.objfn(lp_crop, c(20, 30))

# 添加各项约束条件
add.constraint(lp_crop, c(1, 2), "<=", 50)  # 土地约束
add.constraint(lp_crop, c(2, 3), "<=", 75)  # 水约束
add.constraint(lp_crop, c(3, 2), "<=", 60)  # 肥料约束
add.constraint(lp_crop, c(1, 2), "<=", 40)  # 劳动力约束

# 添加非负约束(关键步骤)
set.bounds(lp_crop, lower = c(0, 0), columns = c(1, 2))

# 求解模型
solve(lp_crop)

# 获取并输出最优解
v <- get.variables(lp_crop)
paste0("# A bushels ", v[1])
paste0("# B bushels ", v[2])

运行修正后的代码,将得到预期的最优解:

[1] "# A bushels 10"
[1] "# B bushels 15"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 18:32:25