约束优化问题:Python

时间:2019-12-30 05:44:17

标签: python optimization

我敢肯定,必须有一个简单的解决方案不断逃避我。 我有一个功能

  

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)

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

3 个答案:

答案 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)

文档在这里:enter link description here