求重心细分后子单纯形顶点的Python实现或工具方案
实现高维单纯形的多重心细分(Python)
核心数学逻辑
重心细分的核心可以通过组合排列+重心生成无缝扩展到任意维度和细分层级:
- 对于由
d+1个顶点张成的d维单纯形(比如K=3时的2维三角形),1次重心细分后的每个子单纯形,对应原顶点的一个全排列。每个排列对应的子单纯形顶点,是排列中前1个、前2个……前d+1个顶点的重心(即子集的算术平均)。例如K=3的标准基单纯形,排列[[1,0,0], [0,1,0], [0,0,1]]对应的子单纯形顶点为[ [1,0,0], (1/2,1/2,0), (1/3,1/3,1/3) ]。 - 多层细分通过递归实现:
m次细分就是对m-1次细分得到的所有子单纯形,再执行1次重心细分。
实现步骤
- 单次细分函数:输入一个
d维单纯形的顶点列表,生成该单纯形1次细分后的所有子单纯形。 - 递归多层细分:输入原单纯形顶点和细分层级,通过迭代调用单次细分函数,完成指定次数的细分。
Python代码实现
import itertools import numpy as np def compute_centroid(points): """计算一组点的重心""" return np.mean(points, axis=0).tolist() def barycentric_subdivide_once(simplex): """对单个d维单纯形执行1次重心细分,返回所有子单纯形""" vertex_count = len(simplex) # d维单纯形有d+1个顶点 sub_simplices = [] # 生成原顶点的所有全排列 for perm in itertools.permutations(simplex): sub_vertices = [] # 依次取前k个顶点的重心,k从1到顶点总数 for k in range(1, vertex_count + 1): centroid = compute_centroid(perm[:k]) sub_vertices.append(centroid) sub_simplices.append(sub_vertices) return sub_simplices def barycentric_subdivide(simplex, levels): """对单纯形执行levels层级重心细分,返回所有子单纯形""" current_simplices = [simplex] for _ in range(levels): next_simplices = [] for s in current_simplices: next_simplices.extend(barycentric_subdivide_once(s)) current_simplices = next_simplices return current_simplices # 测试示例:K=3(2维单纯形),1次细分 original_simplex = [[1,0,0], [0,1,0], [0,0,1]] subdivided = barycentric_subdivide(original_simplex, 1) print(f"1次细分后子单纯形数量:{len(subdivided)}") # 输出6,符合预期 # 打印第一个子单纯形的顶点(保留3位小数) print("第一个子单纯形顶点:") for pt in subdivided[0]: print(np.round(pt, 3))
注意事项
- 高维(d>3)和多层级细分会产生指数级增长的子单纯形数量,计算时需注意性能瓶颈,可按需加入结果过滤或剪枝逻辑。
- 代码使用numpy处理重心计算以保证数值稳定性,也可替换为纯Python列表运算。
内容的提问来源于stack exchange,提问作者Joe Emmens
相关产品推荐
相关产品推荐

