繁体   English   中英

约束优化问题:Python

[英]Constrained Optimization Problem : Python

我敢肯定,一定有一个简单的解决方案一直在逃避我。 我有一个功能

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)

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

您最初所说的没有整数约束的问题可以通过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)

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

您需要将约束更改为“平等约束”。 此外,您的问题没有指定需要整数答案,因此对于这个背包问题有一个更好的非整数答案。 (我对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])

就像杰夫说的, 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)

文档在这里:在此处输入链接描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM