【问题标题】:Evaluate the weights of a convex combination评估凸组合的权重
【发布时间】:2021-09-18 01:05:03
【问题描述】:

我正在使用 scipy.spatial.ConvexHull API 来评估一组点的凸包,并且效果很好。给定以下代码:

p1 = points[11]
hull = ConvexHull(points)
vertices = [points[i] for i in hull.vertices] 

如何评估等于p1vertices 凸组合的系数(权重)?

非常感谢, 摩西

【问题讨论】:

  • 如果vertices中的点数大于d+1,其中d是维度,那么组合将是唯一的。
  • 一种可能性是搜索顶点 A、B、C 的三元组,使得 p1 包含在三角形 A、B、C 中;然后求解stackoverflow.com/a/2049712/3080723 中描述的两个线性方程组,以使用这三个顶点找到系数。
  • @Stef,有没有一种简单的方法来检查一个点是否包含在三角形中,特别是对于 N 点? Python 实现会更好吗?
  • @Stef,刚刚意识到对于 3D 和更高 D 点,三角形包含是不够的。
  • 在维度 2 中,是的,我在之前的评论中给出的链接描述了几种检查点是否在三角形内的方法。在维度d 中,不要搜索三元组;而是搜索 (d+1)-tuple,并检查该点是否包含在此形状内。

标签: math convex-hull convex convex-polygon scipy-spatial


【解决方案1】:

注意:如果顶点的数量大于d+1,其中d 是维度,那么组合将是唯一的。在答案的其余部分,我假设d=2 为简单起见。

输入:

  • 顶点v0 = (x0, y0), v1 = (x1, y1), ..., vn = (xn, yn);
  • 一点p1 = (x,y);

输出:

  • 组合a0, a1, ..., an;

这样:

  • x = a0 * x0 + a1 * x1 + ... + an * xn;
  • y = a0 * y0 + a1 * y1 + ... + an * yn;
  • 1 = a0 + a1 + ... + an;
  • 我,ai >= 0

这是一个由未知(a0, a1, ..., an) 中的三个线性方程组以及 n+1 个线性方程组组成的系统。我们可以使用scipy's linear programming module scipy.optimize.linprog解决这个系统

示例解决方案:

import random                      # generate points
import scipy.spatial as scispa     # ConvexHull
import scipy.optimize as sciopt    # linprog
from scipy.sparse import identity  # identity matrix

points = [(random.randrange(0,100), random.randrange(0,100)) for _ in range(20)]
p1 = points[11]
hull = scispa.ConvexHull(points)
vertices = [points[i] for i in hull.vertices]

c = [1 for _ in vertices]
A = [[x for x,y in vertices], [y for x,y in vertices], [1 for _ in vertices]]
b = [p1[0], p1[1], 1]
s = sciopt.linprog(c, A_eq = A, b_eq = b)

>>> s.x
array([0.13393774, 0.06470577, 0.07367599, 0.09523271, 0.18924727,
       0.26909487, 0.17410566])
>>> p1
(36, 57)
>>> [sum(a*xi for a,(xi,_) in zip(s.x, vertices)), sum(a*yi for a,(_,yi) in zip(s.x, vertices))]
[36.00000000719907, 57.00000000671608]

重要提示:我开始回答这个问题时警告说,如果平面上有超过 3 个顶点,或者维度 d 中有超过 d+1 个顶点,那么将有超过 1 个解决方案到我们的方程组。上面的代码只返回一个解决方案,这意味着做出了任意选择。您可以控制这个任意选择:scipy.optimize.linprog 是一个优化工具;这里是最小化我们作为参数给出的向量c 和解向量s.x 的点积。这里我将c的所有系数都设置为1,意思是linprog会找到一个解,使解中的系数总和最小;尝试提供不同的向量c,你会得到不同的解决方案。

【讨论】:

  • 谢谢。您的解决方案对我来说证明了合理的性能,至少对于小数据集和低维是这样。稍后我将针对更高维向量的更大数据集对其进行测试。再次感谢您。
猜你喜欢
  • 2013-11-10
  • 1970-01-01
  • 2019-06-02
  • 2017-04-13
  • 1970-01-01
  • 2019-06-20
  • 1970-01-01
  • 2020-08-19
  • 2019-06-04
相关资源
最近更新 更多