我有一个实数x_i
的数组x
。其中一些值高于阈值常数c
,因此需要对c
以上的值进行裁剪,并将裁剪的量重新分配给数组中的其他元素。
x_i
的变换受以下约束:
x_i
<c
为所有i,其中c
为已知阈值常数>sum(x)
需要近似为零(尽可能接近零)sum(abs(x))
需要小于某个已知常数g
x
中值的变化应该是最小的,所以这本质上是优化问题。
我不确定这是什么类型的优化问题,如何解决它(如果有的话)或阅读什么相关文献。如果有人知道这个优化问题的具体类型,任何可以解决它的算法,或者我怎么去解决它,那将是非常感谢的。
所以,一个高级模型可以是这样的:
min sum(|x[i]-x0[i]|)
x[i] <= c
sum(x[i]) = 0
sum(|x(i)|) <= g
一些代码来测试一下:
import cvxpy as cv
import numpy as np
n = 20
c = 7 # x <= c
g = 80 # sum(abs(x)) <= g
x0 = np.random.default_rng(123).uniform(-10,+10,n)
print(f"x0:n{x0}")
x = cv.Variable(n)
prob = cv.Problem(
cv.Minimize(cv.sum(cv.abs(x-x0))),
[x<=c, cv.sum(x)==0, cv.sum(cv.abs(x)) <= g]
)
prob.solve()
print(f"x:n{x.value}")
print(f"sum(x) :{sum(x.value)}nsum(|x|) :{sum(np.abs(x.value))}nmax(x) :{max(x.value)}")
输出:
x0:
[ 3.64703726 -8.92357962 -5.59280254 -6.31256379 -6.48188198 6.24189013
8.46689996 -4.46851204 6.39509123 7.79785386 0.2594091 -5.10070798
6.48483192 -5.72474073 4.82934104 2.59880409 8.54814517 -5.36183623
5.98250257 0.36330074]
x:
[ 2.42801305 -7.52326449 -4.65566667 -5.28888531 -5.43657677 4.22054525
5.19677348 -3.65389826 4.31045304 4.97952779 0.10872304 -4.2185185
4.3617407 -4.77234867 3.28537387 1.66750902 5.21912779 -4.45084134
4.0620259 0.16018709]
sum(x) :4.85722573273506e-15
sum(|x|) :79.99999999776362
max(x) :5.219127785064835