如何用Gekko实现Hausdorff距离?适配Gekko变量数组的代码修改方法
Gekko实现Hausdorff距离及适配Gekko变量的代码修改
1. 用Gekko实现Hausdorff距离的核心思路
Gekko是面向优化建模的工具,无法直接使用Python原生的条件判断和循环极值逻辑处理Gekko变量,必须通过其内置的极值函数(m.min2()、m.max2())构建表达式。
Hausdorff距离的本质是两个点集间的双向最大最小距离,标准定义为:
H(A,B) = max( supₐ∈ᵃ infᵦ∈ᵦ d(a,b), supᵦ∈ᵦ infₐ∈ᵃ d(a,b) )
实现时需拆解为两步:
- 对每个点集中的点,计算到另一个点集所有点的距离,用
m.min2()取最小值(对应inf操作) - 用
m.max2()取所有最小值的最大值(对应sup操作),得到单向距离 - 最终Hausdorff距离为两个单向距离的最大值
2. 适配Gekko变量的代码修改方案
原函数依赖np.inf和Python原生条件判断,无法处理Gekko变量,需做以下调整:
替换np.inf的方案
不能直接使用np.inf,需设定一个远大于数据集可能出现的最大距离的常数作为初始最小值。例如若点集坐标范围在[-100, 100],n维点的最大距离为sqrt((200)² * n),可设初始值为1e6(确保远大于该最大值)。
修改后的完整代码
from gekko import GEKKO def hausdorff_distance_gekko(A, B, m=None): """ 计算包含Gekko变量的点集A、B之间的Hausdorff距离 参数: A: Gekko变量数组,形状(N, n_dim) B: Gekko变量数组,形状(M, n_dim) m: Gekko模型实例,未传入则自动创建 """ if m is None: m = GEKKO(remote=False) # 计算A中每个点到B的最小距离,再取最大值 min_dists_A = [] for a in A: min_dist = m.Const(1e6) # 用大常数替代np.inf for b in B: # 用Gekko函数计算欧氏距离 diff = a - b dist = m.sqrt(m.sum([d**2 for d in diff])) # 用m.min2更新最小距离 min_dist = m.min2(min_dist, dist) min_dists_A.append(min_dist) max_A = m.max2(*min_dists_A) # 计算B中每个点到A的最小距离,再取最大值(标准Hausdorff需双向计算) min_dists_B = [] for b in B: min_dist = m.Const(1e6) for a in A: diff = b - a dist = m.sqrt(m.sum([d**2 for d in diff])) min_dist = m.min2(min_dist, dist) min_dists_B.append(min_dist) max_B = m.max2(*min_dists_B) # 最终Hausdorff距离为两个方向的最大值 hausdorff_dist = m.max2(max_A, max_B) return hausdorff_dist
关键修改点说明
- 用
m.min2()和m.max2()替代Python原生if判断,确保Gekko能识别并处理极值逻辑 - 用大常数替代
np.inf,避免Gekko变量与无穷值的无效运算 - 欧氏距离改用Gekko的
m.sqrt()和m.sum()计算,替换无法处理Gekko变量的np.linalg.norm - 支持传入已有Gekko模型实例,方便在复杂优化场景中复用
注:若仅需要原函数中的单向距离(仅计算A到B的最大最小距离),可省略B到A的计算逻辑,直接返回
max_A
内容的提问来源于stack exchange,提问作者Aaron John Sabu
相关产品推荐
相关产品推荐

