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

如何在Python中为多条多项式曲线拟合凸包?

寻找覆盖多条多项式曲线的凸包的Python实现

我有若干已知表达式的多项式曲线,组合效果如图所示,需要找到能覆盖所有曲线的凸包(类似图中蓝色曲线),想知道Python有没有相关实现函数。

以下是各曲线的函数表达式:

y = 0.00867 * x + -0.00001 * x^2 + 0.00000* x^3+ 24.08735
y = 0.00314 * x + -0.00000 * x^2 + 25.50681
y = 0.00092 * x + -0.00000 * x^2 + 28.09722
y = 0.00480 * x + -0.00000 * x^2 + 30.29156
y = 0.00255 * x + -0.00000 * x^2 + 36.37911

解决方案

你需要的其实是上包络线(逐点取所有曲线在对应x处的最大值,连接后形成的曲线),而非传统的点集凸包。Python可以通过numpy和matplotlib轻松实现,步骤如下:

  1. 定义多项式函数:将每个表达式转换为可计算的多项式对象,使用numpy.poly1d(注意系数按高次到低次排列)。
  2. 生成采样点:确定x的取值区间,生成足够多的采样点以捕捉曲线细节。
  3. 计算上包络线:对每个x点,计算所有曲线的y值并取最大值,得到包络线的y值。
  4. 可视化验证:绘制原始曲线和包络线,确认覆盖效果。

示例代码

import numpy as np
import matplotlib.pyplot as plt

# 转换所有多项式为numpy可计算的对象(系数从高次到低次排列)
polynomials = [
    np.poly1d([-0.00001, 0.00867, 24.08735]),  # 对应第一条曲线
    np.poly1d([0, 0.00314, 25.50681]),        # 对应第二条曲线
    np.poly1d([0, 0.00092, 28.09722]),        # 对应第三条曲线
    np.poly1d([0, 0.00480, 30.29156]),        # 对应第四条曲线
    np.poly1d([0, 0.00255, 36.37911])         # 对应第五条曲线
]

# 设置x的取值范围(根据实际需求调整区间和采样点数量)
x = np.linspace(0, 1000, 1000)

# 计算每个x点对应的所有曲线y值,取最大值得到上包络线
y_envelope = np.max([poly(x) for poly in polynomials], axis=0)

# 绘制结果
plt.figure(figsize=(10, 6))
# 绘制原始曲线
for idx, poly in enumerate(polynomials):
    plt.plot(x, poly(x), alpha=0.6, label=f"曲线{idx+1}")
# 绘制上包络线
plt.plot(x, y_envelope, color='blue', linewidth=2, label='覆盖所有曲线的上包络线')

plt.xlabel('x')
plt.ylabel('y')
plt.title('多项式曲线及上包络线')
plt.legend()
plt.show()

补充说明

如果确实需要传统的点集凸包(将所有曲线上的采样点合并后计算凸包),可以使用scipy.spatial.ConvexHull:

from scipy.spatial import ConvexHull

# 采样所有曲线上的点
all_points = []
for poly in polynomials:
    y = poly(x)
    all_points.extend(np.column_stack((x, y)))
all_points = np.array(all_points)

# 计算凸包
hull = ConvexHull(all_points)

# 绘制凸包
plt.figure(figsize=(10,6))
plt.plot(all_points[:,0], all_points[:,1], 'o', alpha=0.3)
for simplex in hull.simplices:
    plt.plot(all_points[simplex, 0], all_points[simplex, 1], 'blue')
plt.show()

但这种方法生成的凸包会包含曲线下方的区域,对于“覆盖所有曲线”的需求,上包络线是更精准的选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 05:35:10