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

带非负约束的线性优化问题求解异常:Python实现疑问

你的线性规划代码问题分析与修复方案

嘿,我帮你找到了代码出问题的关键原因,还有更贴合需求的解决办法:

1. 最核心的错误:约束类型设置错误

你要的约束是严格等式 x + 2y + 4z = 5,但代码里把它定义成了不等式约束(type='ineq'),这会让优化器认为只要满足x + 2y + 4z ≥ 5就符合要求,完全偏离了你的原始需求!

正确的做法是把约束类型改成'eq',并且去掉约束函数里多余的sign参数——等式约束只要求函数返回值等于0就行。

2. 修正后的SLSQP版本代码

我调整了约束和目标函数的写法,现在能输出你期望的结果:

import numpy as np
from scipy.optimize import minimize

def objective(x):
    # 因为minimize默认求最小值,所以返回目标函数的相反数来实现最大化
    return -(2*x[0] + 4*x[1] + 10*x[2])

def constraint_eq(x):
    # 等式约束:返回值必须等于0
    return x[0] + 2*x[1] + 4*x[2] - 5

# 初始猜测值
x0 = [0, 0, 0]
# 变量非负约束
bnds = [(0, None), (0, None), (0, None)]
# 定义等式约束
cons = [{'type': 'eq', 'fun': constraint_eq}]

# 求解
sol = minimize(objective, x0, method='SLSQP', bounds=bnds, constraints=cons)

# 打印结果(取整是因为优化器可能返回极小的小数)
print("最优解:")
print(f"x = {round(sol.x[0])}, y = {round(sol.x[1])}, z = {round(sol.x[2])}")
print(f"最大化的f值:{round(-sol.fun)}")

运行这段代码就能得到x=1, y=0, z=1,f=12的结果。

3. 更高效的选择:用线性规划专用工具

你的问题是标准的线性规划(目标函数和约束都是线性的),用scipy.optimize.linprog会比通用的SLSQP更合适,不需要手动转最大化逻辑:

from scipy.optimize import linprog

# linprog默认求最小值,所以传入目标函数的相反数系数
c = [-2, -4, -10]
# 等式约束的矩阵和右侧值
A_eq = [[1, 2, 4]]
b_eq = [5]
# 变量非负约束
bounds = [(0, None), (0, None), (0, None)]

# 求解(推荐用highs方法,效率更高)
res = linprog(c, A_eq=A_eq, b_eq=b_eq, bounds=bounds, method='highs')

print("最优解:")
print(f"x = {round(res.x[0])}, y = {round(res.x[1])}, z = {round(res.x[2])}")
print(f"最大化的f值:{round(-res.fun)}")

为什么理想解是x=1,y=0,z=1?

线性规划的最优解一定在可行域的顶点上。咱们算下每个变量的"性价比":

  • z:每消耗4个B值,带来10的f,性价比2.5
  • x:每消耗1个B值,带来2的f,性价比2
  • y:每消耗2个B值,带来4的f,性价比2

所以优先把B值分配给z,最多能分配4(对应z=1),剩下的1个B值分配给x或y都能得到2的f,所以x=1,y=0,z=1和x=0,y=0.5,z=1都是最优解,f都是12——你想要的整数解只是其中一个顶点罢了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:10:51