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

pbwdgjma  于 2023-04-30  发布在  其他
关注(0)|答案(1)|浏览(165)

我正在尝试使用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

问题是,这是不工作的一些原因和限制,我已经尝试了不同的方法,它不断产生一个错误。

gudnpqoy

gudnpqoy1#

是的,它可以(显著地)“压缩”。将 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来观察。

相关问题