我敢肯定,必须有一个简单的解决方案不断逃避我。 我有一个功能
f = a x + b y + c * z
和约束
l x + m y + 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)
这产生了奇怪的解决方案。我想念什么?
答案 0 :(得分:1)
您最初所说的没有整数约束的问题可以通过linprog
简单有效地解决:
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)
我建议您不要使用更多通用的求解器来解决诸如此类的狭窄问题,因为您常常会遇到性能下降甚至有时会出乎意料的结果。
答案 1 :(得分:0)
您需要将约束更改为“平等约束”。另外,您的问题没有指定需要整数答案,因此对于此背包问题有更好的非整数答案。 (我对scipy.optimize
没有太多的经验,我不确定它是否可以解决整数LP问题。)
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])
答案 2 :(得分:0)
就像Jeff所说的那样,scipy.optimize仅适用于线性编程问题。
对于整数优化问题,您可以尝试使用PuLP:
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)