如何在两个向量之间的差异上使用scipy``最小''?
我有两个向量w1
和w2
(长度100中的每个),我想最大程度地减少其绝对差异的总和,即
import numpy as np
def diff(w: np.ndarray) -> float:
"""Get the sum of absolute differences in the vector w.
Args:
w: A flattened vector of length 200, with the first 100 elements
pertaining to w1, and the last 100 elements pertaining to w2.
Returns:
sum of absolute differences.
"""
return np.sum(np.absolute(w[:100] - w[-100:]))
我需要编写diff()
仅作为一个参数,因为scipy.opyimize.minimize
要求传递给x0
参数的数组为1维。
至于约束,我有
w1
是固定的, 允许更改w2
更改- 绝对值的总和
w2
w2 < /code>在0.1和1.1之间:
0.1&lt; = sum(abs(w2))&lt; = 1.1
| w2_i | &lt; 0.01
对于任何元素i
inw2
> i
我对我们如何使用 bunds
和 lineArconstraints
对象。到目前为止,我尝试的是
from scipy.optimize import minimize, Bounds, LinearConstraint
bounds = Bounds(lb=[-0.01] * 200, ub=[0.01] * 200) # constraint #4
lc = LinearConstraint([[1] * 200], [0.1], [1.1]) # constraint #3
res = minimize(
fun=diff,
method='trust-constr',
x0=w, # my flattened vector containing w1 first 100 elements, and w2 in last 100 elements
bounds=bounds,
constraints=(lc)
)
bends
变量的以下逻辑来自约束#4,而lc
变量变量来自约束#3。但是我知道我已经对此进行了编码,因为因为上下界限为200,这似乎表明它们都应用于w1
和w2
't将约束应用于w2
(我得到错误value> value eRror:操作数不能与形状(200,)(100)(100,)
一起播放,如果我尝试更改界限
的数组长度从200到100)。
lineArconstraint
的形状和参数类型对我特别令人困惑,但是我确实尝试遵循 scipy示例。
当前的实施似乎从未完成,它永远悬而未决。
我如何正确实现bunds
和linearconstraint
,以便满足我上面的约束列表,即使这甚至可能?
I have two vectors w1
and w2
(each of length 100), and I want to minimize the sum of their absolute difference i.e.
import numpy as np
def diff(w: np.ndarray) -> float:
"""Get the sum of absolute differences in the vector w.
Args:
w: A flattened vector of length 200, with the first 100 elements
pertaining to w1, and the last 100 elements pertaining to w2.
Returns:
sum of absolute differences.
"""
return np.sum(np.absolute(w[:100] - w[-100:]))
I need to write diff()
as only taking one argument since scipy.opyimize.minimize
requires the array passed to the x0
argument to be 1 dimensional.
As for constraints, I have
w1
is fixed and not allowed to changew2
is allowed to change- The sum of absolute values
w2
is between 0.1 and 1.1:0.1 <= sum(abs(w2)) <= 1.1
|w2_i| < 0.01
for any elementi
inw2
I am confused as to how we code these constraints using the Bounds
and LinearConstraints
objects. What I've tried so far is the following
from scipy.optimize import minimize, Bounds, LinearConstraint
bounds = Bounds(lb=[-0.01] * 200, ub=[0.01] * 200) # constraint #4
lc = LinearConstraint([[1] * 200], [0.1], [1.1]) # constraint #3
res = minimize(
fun=diff,
method='trust-constr',
x0=w, # my flattened vector containing w1 first 100 elements, and w2 in last 100 elements
bounds=bounds,
constraints=(lc)
)
My logic for the bounds
variable is from constrain #4, and for the lc
variable comes from constrain #3. However I know I've coded this wrong because because the lower and upper bounds are of length 200 which seems to indicate they are applied to both w1
and w2
whereas I only wan't to apply the constrains to w2
(I get an error ValueError: operands could not be broadcast together with shapes (200,) (100,)
if I try to change the length of the array in Bounds
from 200 to 100).
The shapes and argument types for LinearConstraint
are especially confusing to me, but I did try to follow the scipy example.
This current implementation never seems to finish, it just hangs forever.
How do I properly implement bounds
and LinearConstraint
so that it satisfies my constraints list above, if that is even possible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的问题很容易被提出为线性优化问题(LP)。您只需要重新调整优化变量的所有绝对值即可。
稍微更改符号(X现在是优化变量W2和W只是您给定的向量W1),您的问题读起来为
EPS只是一个足够小的数量,以建模严格的不平等。
让我们考虑约束(3)。在这里,我们添加其他正变量z并定义z_i = | x_i |。然后,我们替换所有绝对值| x_i |由z_i强加了约束-x_i&lt; = z_i&lt; = x_i,将关系建模为z_i = | x_i |。同样,您可以进行目标和约束(4)。后者是琐碎的,相当于 - (0.01 -eps)&lt; = x_i&lt; = 0.01 -eps。
最后,您的优化问题应读取(假设所有W_I都是肯定的):
使用3*n优化变量x1,...,xn,u1,...,un,Z1,...,Zn。将这些约束写入矩阵矢量乘积A_ineq * x&lt; = b_ineq并不难。然后,您可以通过
scipy。 Optimize.linprog
如下:某些笔记以任意顺序:
强烈建议用
linprog
而不是最小化
。前者提供了一个高点的接口,高性能Lp solver highs 在<代码的hood of最小化。但是,还值得一提的是,
最小化
用于非线性优化问题。如果您的值W并非全部为正,我们需要更改公式。
Your problem can easily be formulated as a linear optimization problem (LP). You only need to reformulate all absolute values of the optimization variables.
Changing the notation slightly (x is now the optimization variable w2 and w is just your given vector w1), your problem reads as
where eps is just a sufficiently small number in order to model the strict inequality.
Let's consider the constraint (3). Here, we add additional positive variables z and define z_i = |x_i|. Then, we replace all absolute values |x_i| by z_i and impose the constraints -x_i <= z_i <= x_i which model the relationship z_i = |x_i|. Similarly, you can proceed with the objective and the constraint (4). The latter is by the way trivial and equivalent to -(0.01 - eps) <= x_i <= 0.01 - eps.
In the end, your optimization problem should read (assuming that all your w_i are positive):
with 3*N optimization variables x1, ..., xN, u1, ..., uN, z1, ..., zN. It isn't hard to write these constraints as an matrix-vector product A_ineq * x <= b_ineq. Then, you can solve it by
scipy.optimize.linprog
as follows:Some notes in arbitrary order:
It's highly recommended to solve linear optimization problems with
linprog
instead ofminimize
. The former provides an interface to HiGHS, a high-performance LP solver HiGHs that outperforms all algorithms under the hood ofminimize
. However, it's also worth mentioning thatminimize
is meant to be used for nonlinear optimization problems.In case your values w are not all positive, we need to change the formulation.
您可以(也许为了清楚起见),在
中使用
,并提供固定的向量作为您函数的额外参数。args
参数最小化如果您按以下方式设置方程式:
以及您的约束
,然后做
:
至少对我来说(至少对我来说),
这似乎是您想要的。
请注意,我的测试输入是:
哪个可能有利于拟合程序。
You can (and perhaps should, for clarity), use the
args
argument inminimize
, and provide the fixed vector as an extra argument to your function.If you set up your equation as follows:
and your constraints with
and then do
Then:
yields (for me at least)
which seems to be what you want.
Note that my test inputs are:
which may or may not be favourable to the fitting procedure.