有两个约束的Python数组优化

问题描述

我遇到一个优化问题,我试图找到一个需要同时优化两个函数的数组。

在下面的最小示例中,我有两个已知的数组wx一个 unkNown 数组y。我将数组y初始化为仅包含1。

然后我指定函数np.sqrt(np.sum((x-np.array)**2),并想在其中找到数组y

np.sqrt(np.sum((x-y)**2)接近5

np.sqrt(np.sum((w-y)**2)接近8

下面的代码可用于相对于单个数组成功优化y,但是我想发现针对yx优化y解决方y同时使用,但不确定如何指定两个约束。

w = np.array([6,3,1,2]) x = np.array([3,4,5,6,7]) y = np.array([1,1]) def func(x,y): z = np.sqrt(np.sum((x-y)**2)) - 5 return np.zeros(x.shape[0],) + z r = opt.root(func,x0=y,method='hybr') print(r.x) # array([1.97522498 3.47287981 5.1943792 2.10120135 4.09593969]) print(np.sqrt(np.sum((x-r.x)**2))) # 5.0 仅应包含大于0的值。

关于如何解决这个问题的任何想法?

emptyinterface.(int)

解决方法

一个选择是使用scipy.optimize.minimize而不是root,这里您有多个求解器选项,其中一些(即SLSQP)允许您指定多个约束。请注意,我更改了变量名称,以使x是要优化的数组,并且yz定义了约束。

from scipy.optimize import minimize
import numpy as np

x0 = np.array([1,1,1])
y = np.array([6,3,2])
z = np.array([3,4,5,6,7])

constraint_x = dict(type='ineq',fun=lambda x: x)   # fulfilled if > 0
constraint_y = dict(type='eq',fun=lambda x: np.linalg.norm(x-y) - 5)  # fulfilled if == 0
constraint_z = dict(type='eq',fun=lambda x: np.linalg.norm(x-z) - 8)  # fulfilled if == 0

res = minimize(fun=lambda x: np.linalg.norm(x),constraints=[constraint_y,constraint_z],x0=x0,method='SLSQP',options=dict(ftol=1e-8))  # default 1e-6

print(res.x)                    # [1.55517124 1.44981672 1.46921122 1.61335466 2.13174483]
print(np.linalg.norm(res.x-y))  # 5.00000000137866
print(np.linalg.norm(res.x-z))  # 8.000000000930026

这是一个最小化器,因此除约束之外,它还希望函数最小化,我只选择了y的范数,但是将函数设置为常量(即lambda x:1)也可以。 还要注意,不能完全满足约束条件,可以通过将可选参数ftol设置为较小的值1e-10来提高准确性。 有关更多信息,请参见documentation和每个求解器的相应部分。