scipy 最小化约束

问题描述 投票:0回答:2

假设我有一个矩阵

arr = array([[0.8, 0.2],[-0.1, 0.14]])

具有目标函数

def matr_t(t):
    return array([[t[0], 0],[t[2]+complex(0,1)*t[3], t[1]]]

def target(t):
    arr2 = matr_t(t)
    ret = 0
    for i, v1 in enumerate(arr):
          for j, v2 in enumerate(v1):
               ret += abs(arr[i][j]-arr2[i][j])**2
    return ret

现在我想在

t[i]
是实数的假设下最小化这个目标函数,比如
t[0]+t[1]=1
.

python math optimization scipy mathematical-optimization
2个回答
65
投票

这个约束

t[0] + t[1] = 1

将是一个等式 (

type='eq'
) 约束,您在其中创建一个必须等于零的函数:

def con(t):
    return t[0] + t[1] - 1

然后你对你的约束做一个

dict
(如果有多个则为字典列表):

cons = {'type':'eq', 'fun': con}

我从未尝试过,但我相信要保持

t
真实,您可以使用:

con_real(t):
    return np.sum(np.iscomplex(t))

让你的

cons
包括两个约束:

cons = [{'type':'eq', 'fun': con},
        {'type':'eq', 'fun': con_real}]

然后你将

cons
喂入
minimize
为:

scipy.optimize.minimize(func, x0, constraints=cons)

0
投票

无需编写自定义约束函数,您可以构造一个

scipy.optimize.LinearConstraint
对象并将其作为约束传递。它的构造要求上限和下限;自变量向量的长度也必须与传递给目标函数的变量长度相同,因此像
t[0] + t[1] = 1
这样的约束应该重新表述如下(因为
t
的长度是4,从它可以看出
matr_t()
中的操纵):

此外,

minimize
对真实空间进行了优化,因此算法中已经嵌入了
t[i]
为真实空间的限制。那么完整的代码就变成了:

import numpy as np
from scipy.optimize import minimize, LinearConstraint

def matr_t(t):
    return np.array([[t[0], 0],[t[2]+complex(0,1)*t[3], t[1]]]

def target(t):
    arr2 = matr_t(t)
    ret = 0
    for i, v1 in enumerate(arr):
          for j, v2 in enumerate(v1):
               ret += abs(arr[i][j]-arr2[i][j])**2
    return ret

arr = np.array([[0.8, 0.2],[-0.1, 0.14]])
linear_constraint = LinearConstraint([[1, 1, 0, 0]], [1], [1])
result = minimize(target, x0=[0.5, 0.5, 0, 0], constraints=[linear_constraint])

x_opt = result.x            # array([ 0.83,  0.17, -0.1 , 0.])
minimum = result.fun        # 0.0418
© www.soinside.com 2019 - 2024. All rights reserved.