You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在scipy的linprog中配置凸包成员问题的约束条件

凸包成员问题的线性规划可行性判断(Scipy linprog实现)

问题转化与约束构建

你的问题本质是凸包成员判定:判断点p是否能表示为给定n个点的正系数凸组合(系数和≤1且每个系数>0)。我们可以将其转化为线性规划可行性问题,用scipy.optimize.linprog求解,约束转化如下:

1. 目标函数

由于仅需判断可行性,无需优化特定目标,设目标函数为全0向量:c = np.zeros(n),让linprog专注寻找满足约束的解。

2. 约束条件拆解

  • 等式约束(点积相等):
    对每个维度m,需满足 $\sum_{k=1}^n a_k \cdot x_{k,m} = p_m$。将点云整理为矩阵X(形状为(n, m),每行是一个m维点),则等式约束的矩阵形式为:
    A_eq = X.T(转置后形状为(m, n),每一行对应一个维度的等式),b_eq = p(目标点的m维向量)。

  • 不等式约束1(系数和≤1):
    约束 $\sum_{k=1}^n a_k ≤ 1$,对应:
    A_ub = np.array([[1]*n])(1行n列的全1矩阵),b_ub = np.array([1])。

  • 不等式约束2(系数>0):
    数值优化中无法严格处理a_k > 0,通常用极小正数近似,设每个系数的下界为1e-9(可根据精度调整),上界无限制:
    bounds = [(1e-9, None) for _ in range(n)]

代码实现示例

import numpy as np
from scipy.optimize import linprog

# 示例数据:3个2维点,目标点p
X = np.array([[0, 0], [1, 0], [0, 1]])  # n=3, m=2
p = np.array([0.2, 0.3])

n = X.shape[0]
m = X.shape[1]

# 构建linprog参数
c = np.zeros(n)
A_ub = np.array([[1]*n])
b_ub = np.array([1])
A_eq = X.T
b_eq = p
bounds = [(1e-9, None) for _ in range(n)]

# 求解线性规划
result = linprog(c, A_ub=A_ub, b_ub=b_ub, A_eq=A_eq, b_eq=b_eq, bounds=bounds, method='highs')

# 判断可行性
if result.status == 0:
    print("可行:点p属于给定点云的凸包内部/边界(满足正系数凸组合条件)")
    print("找到的系数:", result.x)
else:
    print("不可行:点p不在给定点云的凸包内,或无法用正系数凸组合表示")

额外专业建议

用linprog是通用线性规划解法,但凸包成员判定有更高效的专用实现:scipy.spatial.ConvexHull的contains_points方法,底层调用Qhull库,速度更快且更贴合问题场景。示例:

from scipy.spatial import ConvexHull

hull = ConvexHull(X)
is_inside = hull.contains_points([p])[0]
# 注意:contains_points判断的是点是否在凸包内部/边界(系数和=1且系数≥0),若需要严格正系数,需额外验证边界情况

如果要求严格正系数(a_k > 0),需排除点p恰好是凸包顶点或在凸包边/面上的情况(此时会有系数为0),可结合上述两种方法:先用contains_points判断是否在凸包内,再用linprog验证是否存在全正系数的解。

内容的提问来源于stack exchange,提问作者Michael Bay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 13:40:27