【问题标题】:Scipy minimize does not take constraints into accountScipy最小化不考虑约束
【发布时间】:2019-07-03 08:19:56
【问题描述】:

我是编程新手,我尝试使用 Python 解决数学优化问题。

这个问题的想法是在尊重一些约束的同时最小化函数的值。这可能看起来很简单,但是由于某种原因,我得到的结果显然不满足约束。

有问题的函数如下(我没有足够的声誉点来发布 LaTeX 方程的图像):

f(a,b,c,d) = 2*a + 3*b + c + 2*d

具有以下约束:

  • a+b=2
  • c+d=8
  • a+c=3
  • b+d=7

我在 Python 中使用 scipy.optimize.minimize 来尝试解决它,这是我的代码:

import numpy as np
import scipy
from scipy.optimize import minimize as min

def f(x):
    return 2*x[0] + 3*x[1] + x[2] + 2*x[3]

cons = ({'type' : 'eq','fun': lambda x: np.array([x[0]+x[1]-2])},
{'type' : 'eq','fun': lambda x: np.array([x[2]+x[3]-8])}, 
{'type':'eq' , 'fun': lambda x: np.array([x[0]+x[2]-3])}, 
{'type':'eq' , 'fun': lambda x: np.array([x[1]+x[3]-7])},
{'type':'ineq' , 'fun': lambda x: np.array([x[0]])},
{'type':'ineq' , 'fun': lambda x: np.array([x[1]])},
{'type':'ineq' , 'fun': lambda x: np.array([x[2]])},
{'type':'ineq' , 'fun': lambda x: np.array([x[3]])},
{'type':'ineq' , 'fun':f})

u = min(f,[1.5,0.5,1.5,6.5],constraints=cons,method='Nelder-Mead',options={'Disp':True,'maxiter':2})

print(u)
print(f(u.x))

它给了我一些不满足等式的 a,b,c,d 值。我确实尝试更改优化方法,但没有帮助。

非常感谢您的任何建议,感谢您的阅读!

【问题讨论】:

  • 会不会是你用错了方法?来自documentation 似乎唯一可用于约束最小化的方法是 COBYLA 和 SLSQP
  • 当我使用 SLSQP 时,它只是给了我最初的猜测……对于 COBYLA,它说它无法处理“eq”类型的约束
  • 我尝试了许多不同的初始条件,最佳值始终是19,这与您在初始条件下获得的值相同(使用SLSQP 方法)。可能是您返回了原始值,因为它们已经为您提供了最佳值。

标签: python optimization scipy


【解决方案1】:

你的目标函数是线性的,你的等式约束是线性的,所以这个问题很简单,可以手动完成。如果你这样做,你会发现一些有趣的事实:

  • 您的一个约束是多余的。例如,您可以删除 a + c = 3,因为其他三个都隐含了该等式。

  • 剩下三个线性方程和四个未知数。这种系统的解决方案是四维空间中的一条直线。这条线的有趣之处在于您的目标函数是常数。它在线上的每个点都有值 19。因此(考虑到不等式约束),具有非负坐标的线上的每个点都是一个解。 特别是你的起点[1.5,0.5,1.5,6.5]上线了,所以是一个解决方案。 [1.9, 0.1, 1.1, 6.9][1.65, 0.35, 1.35, 6.65] 或实际上是 [0, 2, 3, 5] + a*[1, -1, -1, 1] 形式的任何点也是如此,其分量不是负数。

【讨论】:

    【解决方案2】:

    来自documentation 的您好,似乎唯一可用于约束最小化的方法是 COBYLA 和 SLSQP,特别是在使用 'eq' 约束时,只有 SLSQP 一种。 这可能有效:

    u = min(f,[1.5,0.5,1.5,6.5],constraints=cons,method='SLSQP')
    

    【讨论】:

    • 感谢您的回答,但是当我使用此方法时,它会回复我最初的猜测
    • 通过改变初始猜测值输出改变u = min(f,[1.5,3.5,1.5,6.5],constraints=cons,options={'maxiter':20})x: array([ 2.75, -0.75, 0.25, 7.75])
    • 我忘了说所有的值都必须是正数,我把它添加到代码中的约束中:python {'type':'ineq' , 'fun': lambda x: np.array([x[0]])}, {'type':'ineq' , 'fun': lambda x: np.array([x[1]])}, {'type':'ineq' , 'fun': lambda x: np.array([x[2]])}, {'type':'ineq' , 'fun': lambda x: np.array([x[3]])},
    猜你喜欢
    • 2013-12-03
    • 2016-05-27
    • 1970-01-01
    • 2017-07-07
    • 2020-08-08
    • 1970-01-01
    • 2017-08-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多