我正在尝试使用 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
问题是由于某些原因这不起作用,并且由于限制我尝试了不同的方法并且它不断产生错误。
是的,它可以(显着)“压缩”。将 x 移到最里面的总和之外,您会看到约束左侧相当于 x 和 a 之和的标量积。此外,约束的左侧根本不会改变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
. 来观察