CVXOPTでの学習課題として以下のことを試みています。不等式制約を削除し、等式制約をいくつか追加することで、ここのコード例に小さな変更を加えました。
from cvxopt import solvers, blas, matrix, spmatrix, spdiag, log, div
solvers.options['show_progress'] = False
import numpy as np
np.random.seed(1)
# minimize p'*log(p)
# subject to
# sum(p) = 1
# sum(p'*a) = target1
# sum(p'*max(a-K,a^2)) = target2
a = np.random.randint(20, 30, size=500)
target1 = 30
target2 = 0.60
K = 26
A = matrix(np.vstack([np.ones(500), a, np.array([max(x-K,x*x) for x in a])]))
b = matrix([1.0, target1, target2])
n = 500
def F(x=None, z=None):
if x is None: return 0, matrix(1.0, (n,1))
if min(x) <= 0: return None
f = x.T*log(x)
grad = 1.0 + log(x)
if z is None: return f, grad.T
H = spdiag(z[0] * x**-1)
return f, grad.T, H
sol = solvers.cp(F, A=A, b=b)
p = sol['x']
しかし、次のことを実行すると:
np.sum(p)
243.52686763225338
これは、最適化の最初の制約に違反しています。ここで何が問題なのかわかりません。(乱数を使用して変数を生成しているため、異なる値が生成されることに注意してください。ただし、私a
のnp.sum(p)
ものと同じ違反を観察する必要があります。
元のリンクの不等式制約を保持し、さらに 2 つの等式制約を追加しても、等式制約に違反します。
確実に使用できる他のパッケージ、つまり維持されているパッケージはありますか?
編集:実行可能な解決策がない場合、実行可能な解決策が見つからないというメッセージが表示されるべきではありませんか?