【问题标题】:How do I use Scipy minimize with constraints and dynamic function如何使用具有约束和动态功能的 Scipy 最小化
【发布时间】:2014-11-18 05:24:31
【问题描述】:

我是 scipy.optimize 模块的新手,需要帮助尝试在公式 V 上使用最小化函数,该公式适用于矩阵并具有 2 个约束,但我不确定我是否正确处理函数的形成或其中之一约束。

M 是一个 NxN 矩阵,但例如我将给出 4x4 矩阵

 [[ 0.00123727  0.00011974  0.00067403  0.00060845]
 [ 0.00011974  0.00736665  0.00165674  0.00053581]
 [ 0.00067403  0.00165674  0.00281547  0.00129646]
 [ 0.00060845  0.00053581  0.00129646  0.00153195]]

X 是一个 1xN 矩阵,其中所有数字都是正数,并且必须加起来为 1,这就是我要解决的问题

约束:

X[0] + X[1] + X[2] + … X[n] = 1

E = X[0]*R[0] + X[1]*R[1] + X[2]*R[2] + … X[n]*R[n] (E is user input)

我试图最小化的功能是:

V = X[0]**2 * M[0][0]  + 2*X[0]*X[1]*M[0][1] + 2*X[0]*X[2]*M[0][2] + 2 * X[0] * X[3] * M[0][3] * X[1]**2 * M[1][1] + ….etc

我目前的代码是

    cons = ({'type': 'eq', 'fun': lambda x: sum(w) - 1})

    args = n, m, w

    answer = scipy.optimize.minimize(func(*args), w, args=(), method='SLSQP',
                                     bounds=((0, None), (0, None)),
                                     constraints=cons)
def func(n, m, x):
    row = 0
    col = 0
    formula = []
    while row < n:
        while col < n:
            if col == row:
                item = (x[row]**2) * m[row][col]
                formula.append(item)
                col += 1
            else:
                item2 = 2 * x[row] * x[col] * m[row][col]
                formula.append(item2)
                col += 1

        row += 1
        col = 0

    return sum(formula)

我难以理解的是如何表达第二个约束。我也不确定我是否正确处理了公式的创建。非常感谢任何帮助

【问题讨论】:

标签: python optimization numpy matrix scipy


【解决方案1】:

正如评论中提到的,这可以通过专门的凸求解器来解决。


from __future__ import print_function

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

# Problem data.
n = 4
M = [
        [0.00123727, 0.00011974, 0.00067403, 0.00060845],
        [0.00011974, 0.00736665, 0.00165674, 0.00053581],
        [0.00067403, 0.00165674, 0.00281547, 0.00129646],
        [0.00060845, 0.00053581, 0.00129646, 0.00153195]]
np.random.seed(1)
R = np.random.randn(n)
E = np.random.randn()

print('R:', R)
print('E:', E)
print()

A = np.matrix([np.ones(n), R])
b = np.matrix([[1], [E]])


def solve_cvxpy():

    # Construct the problem.
    x = cvxpy.Variable(n)
    objective = cvxpy.Minimize(cvxpy.quad_form(x, M))
    constraints = [0 <= x, A*x == b]
    problem = cvxpy.Problem(objective, constraints)

    # Solve the problem.
    result = problem.solve()
    print('cvxpy solution:')
    print(x.value)
    print()


def solve_scipy():
    def simplex_constraint(x):
        return x.sum() - 1
    def dot_constraint(x):
        return x.dot(R) - E
    def objective(x):
        return x.dot(M).dot(x)
    x0 = np.ones(n) / n
    bounds = [(0, np.inf)]*n
    constraints = (
            dict(type='eq', fun=simplex_constraint),
            dict(type='eq', fun=dot_constraint))
    result = minimize(
            objective, x0, method='SLSQP', tol=1e-8,
            bounds=bounds, constraints=constraints)
    print('scipy solution:')
    print(result.x)
    print()

solve_cvxpy()
solve_scipy()

R: [ 1.62434536 -0.61175641 -0.52817175 -1.07296862]
E: 0.865407629325

cvxpy solution:
[[  7.03877116e-01]
 [  8.62848827e-02]
 [  5.54383296e-06]
 [  2.09832457e-01]]

scipy solution:
[  7.03877583e-01   8.62886986e-02  -1.24818775e-17   2.09833718e-01]

【讨论】:

    猜你喜欢
    • 2017-08-01
    • 1970-01-01
    • 2020-03-22
    • 2013-12-03
    • 2020-08-08
    • 2013-09-17
    • 2016-05-27
    • 1970-01-01
    • 2014-08-14
    相关资源
    最近更新 更多