如何使用 SciPy 以紧凑的形式编写优化问题?

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

我正在尝试使用 SciPy 在 python 中实现一个非线性程序。问题是我的模型涉及大量约束,我想知道是否有一种方法可以像在 LINGO 等其他优化软件中那样以紧凑的形式编写它。

问题如下:

Objective Function -> Min Z = (n : ℕ) : --(sum from k=1 to k=n) x(k)^2
s.t 
(for all values from k=1 to k=(n-1)) : x(k) <= x(k+1)

我试过这样的东西:

def Objective(x):
    sum = 0
    for i in range(number of days):
       sum += x[i]*x[i]
    return sum

问题是由于某些原因这不起作用,并且由于限制我尝试了不同的方法并且它不断产生错误。

python-3.x scipy mathematical-optimization
1个回答
0
投票

是的,它可以(显着)“压缩”。将 x 移到最里面的总和之外,您会看到约束左侧相当于 xa 之和的标量积。此外,约束的左侧根本不会改变i,这意味着右侧应该丢弃除

max()
之外的所有行。

这给我们留下了:

import numpy as np
from numpy.random import default_rng
from scipy.optimize import minimize, LinearConstraint, NonlinearConstraint


def z(xa: np.ndarray) -> float:
    x = xa[:n]
    return x.dot(x)


def constraint_product(xa: np.ndarray) -> float:
    x = xa[:n]
    a = xa[-h:]
    return x.sum()*a.sum()


rand = default_rng(seed=0)

m = 5
n = 7
h = 11
Cap = rand.random(size=m)

A_monotonic = np.hstack((
    np.zeros((h-1, n)),
    -np.eye(h-1, h) + np.eye(h-1, h, 1),
))

x0 = np.full(n, np.sqrt(Cap.max())/n)
a0 = np.full(h, np.sqrt(Cap.max())/h)
xa0 = np.concatenate((x0, a0))

result = minimize(
    fun=z,
    x0=xa0,
    constraints=[
        LinearConstraint(
            A=A_monotonic,
            lb=0, ub=np.inf,
        ),
        NonlinearConstraint(
            fun=constraint_product,
            lb=Cap.max(), ub=np.inf,
        ),
    ],
)
print(result)
assert result.success

# validation
x = result.x[:n]
a = result.x[-h:]
print('x =', x)
print('a =', a)
for i in range(m):
    total = 0
    for k in range(n):
        for j in range(h):
            total += x[k] * a[j]
    print(f'{total:.3f} >= {Cap[i]:.3f}')
 message: Optimization terminated successfully
 success: True
  status: 0
     fun: 2.5145689445002967e-06
       x: [ 5.634e-04  5.159e-04 ...  1.791e+01  1.791e+01]
     nit: 23
     jac: [ 1.102e-03  1.122e-03 ...  0.000e+00  0.000e+00]
    nfev: 443
    njev: 23
x = [0.00056337 0.00051586 0.00056337 0.00051545 0.00056474 0.00068027
 0.00075254]
a = [17.91043939 17.91043939 17.91043939 17.91043939 17.91043939 17.91043939
 17.91043939 17.91043939 17.91043939 17.91043939 17.91043939]
0.819 >= 0.637
0.819 >= 0.270
0.819 >= 0.041
0.819 >= 0.017
0.819 >= 0.813

但重要的是,请注意这个问题在对数意义上是无界的。最好的解决方案是 x 接近 0 且 a 接近无穷大。这可以通过降低

tol
.

来观察
© www.soinside.com 2019 - 2024. All rights reserved.