约束优化问题:Python

约束优化问题:Python,python,optimization,Python,Optimization,我确信,一定有一个简单的解决方案一直在回避我。 我有一个函数 f=ax+by+c*z 还有一个约束 lx+my+n*z=B 需要找到(x,y,z),根据约束使f最大化。 我也需要 x、 y,z>=0 我记得见过这样的解决方案。 本例使用 a、 b,c=2,4,10和l,m,n=1,2,4和b=5 理想情况下,这应该给我x=1,y=0,z=1,这样f=12 import numpy as np from scipy.optimize import minimize def objective(x,

我确信,一定有一个简单的解决方案一直在回避我。 我有一个函数

f=ax+by+c*z

还有一个约束

lx+my+n*z=B

需要找到(x,y,z),根据约束使f最大化。 我也需要

x、 y,z>=0

我记得见过这样的解决方案。 本例使用

a、 b,c=2,4,10和l,m,n=1,2,4和b=5

理想情况下,这应该给我x=1,y=0,z=1,这样f=12

import numpy as np
from scipy.optimize import minimize
def objective(x, sign=-1.0):
    x1 = x[0]
    x2 = x[1]
    x3 = x[2]
    return sign*((2*x1) + (4*x2)+(10*x3))
def constraint1(x, sign=1.0):
    return sign*(1*x[0] +2*x[1]+4*x[2]- 5)

x0=[0,0,0]

b1 = (0,None)
b2 = (0,None)
b3=(0,None)
bnds= (b1,b2,b3)
con1 = {'type': 'ineq', 'fun': constraint1}

cons = [con1]
sol = minimize (objective,x0,method='SLSQP',bounds=bnds,constraints=cons)

print(sol)

这产生了奇怪的解决方案。我缺少什么?

您需要将约束更改为“相等约束”。另外,您的问题没有指定需要整数答案,所以对于这个背包问题有一个更好的非整数答案。(我对
scipy.optimize
没有太多经验,也不确定它是否能解决整数LP问题。)


正如杰夫所说,scipy.optimize只适用于线性规划问题

In [13]: con1 = {'type': 'eq', 'fun': constraint1}                                               

In [14]: cons = [con1,]                                                                          

In [15]: sol = minimize (objective,x0,method='SLSQP',bounds=bnds,constraints=cons)               

In [16]: print(sol)                                                                              
     fun: -12.5
     jac: array([ -2.,  -4., -10.])
 message: 'Optimization terminated successfully.'
    nfev: 10
     nit: 2
    njev: 2
  status: 0
 success: True
       x: array([0.  , 0.  , 1.25])
您可以尝试使用纸浆代替整数优化问题:

from pulp import *

prob = LpProblem("F Problem", LpMaximize)

# a,b,c=2,4,10 and l,m,n=1,2,4 and B=5
a,b,c=2,4,10
l,m,n=1,2,4
B=5

# x,y,z>=0
x = LpVariable("x",0,None,LpInteger)
y = LpVariable("y",0,None,LpInteger)
z = LpVariable("z",0,None,LpInteger)

# f=ax+by+c*z
prob += a*x + b*y + c*z, "Objective Function f"

# lx+my+n*z=B
prob += l*x + m*y + n*z == B, "Constraint B"

# solve
prob.solve()

print("Status:", LpStatus[prob.status])

for v in prob.variables():
  print(v.name, "=", v.varValue)

文档如下:

如您最初所述,没有整数约束的问题可以通过以下方式简单有效地解决:


我建议不要使用更多的通用解算器来解决这样的狭隘问题,因为您经常会遇到性能更差的问题,有时还会遇到意想不到的结果。

谢谢Jeff!!你对背包问题的评论使我找到了正确的方法。显然,这是动态规划的一个实例。事实上,我在寻找一个整数解。@Arindam很好!很高兴它成功了。认识到动态规划是解决背包问题的一种方法。我认为上述SLSQP方法更适用于非线性应用。如果你想使用一个解算器来解决这个问题,我认为大多数人会在施加整数约束时使用分支和边界来解决这类问题。
import scipy.optimize

c = [-2, -4, -10]
A_eq = [[1, 2, 4]]
b_eq = 5

# bounds are for non-negative values by default

scipy.optimize.linprog(c, A_eq=A_eq, b_eq=b_eq)