【问题标题】:scipy.opimize.minimize fails with constraints for ordered solution vectorscipy.optimize.minimize 因有序解向量的约束而失败
【发布时间】:2021-10-09 07:55:48
【问题描述】:

我正在尝试用最小化(算法 = SLSQP)求解线性方程组,具有一组约束:解向量分量的总和必须为 1(或至少非常接近它,以最小化误差)第二个约束强制对向量分量进行排序,其中 x_0 最大,x_n 最小。此外,我设置了界限,因为每个向量分量都有

这是我目前的代码:

from scipy.optimize import minimize
import numpy as np
from scipy.sparse import rand
from scipy.optimize import lsq_linear

#Linear equation Ax = b


def fmin(x,A,b):
    y = np.dot(A, x) - b
    return np.dot(y, y)


#Test data
b = np.array([172,8,7.4,24,21,0.8,0.1]) 

A_t = np.array(
    [[188,18.4,16.5,3.4,2.1,1.77,0.075],
     [405,0,0,99.8,99.8,0,0.0054],
     [90.5,0.4,0.009,19.7,15.6,1.06,0.012],
     [322,0,0,79,79,0.3,0.3],
     [0,0,0,0,0,0,0],
     [362,0.25,0.009,89.2,0,0.43,0.019],
     [37,1.4,0.2,7.3,1,4.5,0.1],
     [26,0.29,0.038,6.1,2.4,0.4,0.053]])
A = A_t.T
#=========================


m = np.shape(A)[0]
n = np.shape(A)[1]


x0 = np.full(n, 0.5) 

args = (A,b)
bnds = (( (1*10e-100, 1), )*n) #all x_i must be between 0 and 1
cons = [{'type': 'eq', 'fun': lambda x: 1.0-np.sum(x) }] #sum(x_i) = 1

#consider order of vectors as constraints
for i in range(n-1):
    cons = cons + [{'type': 'ineq', 'fun': lambda x : x[i] - x[i+1] }]

res = minimize(fmin, x0, args, method='SLSQP',
bounds=bnds,constraints=cons,tol=1e-2,options={'disp': False})

print ("\n res\n", res)
print("Sum of coefficients {}".format(np.sum(res.x)))
print("Difference vector:\n{}".format(np.dot(A,res.x) - b))

不幸的是算法错误

 res
      fun: 317820.09898084006
     jac: array([205597.34765625, 481389.625     , 105853.7265625 , 382592.76953125,
            0.        , 416196.953125  ,  42268.78125   ,  30196.81640625])
 message: 'Positive directional derivative for linesearch'
    nfev: 10
     nit: 5
    njev: 1
  status: 8
 success: False
       x: array([0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5])
Sum of coefficients 4.0
Difference vector:
[5.4325e+02 2.3700e+00 9.7800e-01 1.2825e+02 7.8950e+01 3.4300e+00
 1.8220e-01]

如果有人能帮我解决这个问题,我将不胜感激。事实上,对于这个例子中的测试数据,我知道正确的解决方案应该是 x_0 的 0.58 和 x_2 的 0.12。 非常感谢!

【问题讨论】:

  • 欢迎来到 SO!这不是一个完整的可重现示例。你的目标是什么fmin?另请注意,minimize 解决了非线性问题,即至少目标或约束之一不是线性的。如果您的目标函数是线性的,您将面临一个可以通过scipy.optimize.linprog 解决的线性问题 (LP)。
  • 嗨,对不起,我刚刚添加了上面缺少的fmin 并更新了最初的帖子。你是对的,这是一个线性问题。我可能需要一些时间来弄清楚如何为新求解器转换上述设置的约束,如果同时没有更容易的适应建议的话。到目前为止谢谢!
  • 如果我的回答有帮助,请考虑accepting and/or upvoting it

标签: python scipy minimize


【解决方案1】:

为了澄清 cmets 中的讨论:您的目标函数在优化变量 x 中是非线性的。因此,这是一个非线性优化问题。错误消息的原因很简单:您最初的猜测x0 位于可行区域之外。您可以轻松验证它不满足您的第一个约束1.0 - np.sum(x) = 0

但是,还请注意,在循环中创建 lambda 约束表达式时,您需要捕获循环变量 i。否则,您添加约束lambda x: x[n-2] - x[n-1] 七次。见,例如here 了解更多详情。

通过

正确创建约束
for i in range(n-1):
    cons = cons + [{'type': 'ineq', 'fun': lambda x, i=i: x[i] - x[i+1] }]

并提供可行的初始猜测x0 = np.ones(n)/n 产量

     fun: 114.90196737679031
     jac: array([3550.86690235, 7911.74978828, 1787.36224174, 6290.006423  ,
          0.        , 7580.9283762 ,  757.60069752,  528.41590595])
 message: 'Optimization terminated successfully'
    nfev: 66
     nit: 6
    njev: 6
  status: 0
 success: True
       x: array([0.38655391, 0.08763516, 0.08763516, 0.08763516, 0.08763516,
       0.08763515, 0.08763516, 0.08763516])

但是,对于较大的问题,强烈建议重写您的第二个约束:

D = np.eye(n) - np.eye(n, k=1)
D[-1, -1] = 0.0

cons = [{'type': 'eq', 'fun': lambda x: 1.0-np.sum(x) }]
cons += [{'type': 'ineq', 'fun': lambda x: D @ x}]

现在求解器只需要在每次迭代中评估 2 个约束而不是 n+1 约束。您可以通过提供梯度和雅可比值来进一步加快求解器速度,see this answer for more details

【讨论】:

  • 感谢您指出这个明显的错误。这很有意义,并且以向量形式放置约束的方式非常优雅。我很惊讶我得到了一个完全不同的解决方案,并且想知道您是否使用了我上面提供的测试数据?出于某种原因,我得到了x: array([0.38656138, 0.08763409, 0.08763409, 0.08763409, 0.08763409, 0.08763409, 0.08763409, 0.08763409]) 作为解决方案。
  • @s1m0n 第二种解决方案是正确的。我在创建约束的初始帖子中忽略了一个错误。我编辑了我的答案。
  • 刚刚有时间深入了解进一步的测试数据。不幸的是,该算法似乎总是吐出一个由以下组成的解向量:x: array([x0, x1, x1, x1, x1, x1, x1, x1])。这意味着第一个向量分量是某个值,所有其他分量都小于第一个,但具有相同的值。毕竟我得到的所有解决方案都不是基本事实解决方案所建议的。对于上述测试数据,我预计 x0 为 0.58,x2 为 0.12。我想知道是否仍然缺少某些东西,或者对于给定的问题和约束,我得到的输出是否是预期的。
  • 抱歉,我非常感谢您迄今为止的意见,感谢您的奉献!不幸的是,我没有资格对任何事情进行投票(我只能以 15 名声望这样做),并且由于尚不清楚您上面的帖子是否是正确答案,所以我没有接受它。但是,我再次勾选它,直到出现更好的答案,但不确定这是否是正确的做法,至于我这个问题还没有完全解决。
  • @s1m0n 您的问题是凸优化问题。因此,每个找到的局部最小化器都是全局最小化器,即没有更好的解决方案。然而,全局最小化器并不是唯一的。因此,可能存在具有相同目标函数值的其他全局最小化器(如您期望的解决方案)。
猜你喜欢
  • 2016-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多