离散Fréchet算法

本文介绍了离散Fréchet算法,一种用于度量二维空间中两条曲线相似度的复杂度量,重点讲解了其原理、直观解释和Python实现。通过计算多边形曲线的耦合距离,提供了一种在O(pq)时间内得到良好近似值的方法,适用于计算Fréchet距离。
摘要由CSDN通过智能技术生成

离散Fréchet算法

总结

实现Fréchet算法的过程中巩固递归算法的基本操作,就是终止条件和Max或Min的计算;而且使用尾递归而不是普通的递归在python和C中实现更好的效率。

Fréchet算法原理1

度量空间中两条曲线之间的 Fréchet 距离是曲线之间相似性的度量。 算法的离散实现提供了连续测量的良好近似值,并且可以使用简单的算法有效地计算。

给定度量空间中的两条曲线,它们之间的 Fréchet 距离 δF 可以直观地定义如下。

一个人用皮带牵狗:人可以在一条曲线上移动,而狗在另一条曲线上;两者都可以改变它们的速度,但不允许回溯。足以穿过两条曲线的最短皮带长度是多少? Fréchet 距离是曲线之间相似性的度量,它考虑了沿曲线的点的位置和顺序。因此它通常比众所周知的豪斯多夫距离要好。这个距离函数是由 Fréchet 在 1906 年引入的 。 Alt 和 Godau对 Fréchet 距离的计算特性进行了基础研究。他们给出了一种算法,可以在 O(pq log2 pq) 时间内计算两条多边形曲线之间的精确 Fréchet 距离,其中 p 和 q 是多边形曲线上的段数。该算法相当复杂,因为它使用参数搜索技术。在本文中,描述了多边形曲线的 Fréchet 距离的离散变化。这种变化称为耦合距离δdF。它基于查看多边形曲线的线段端点之间所有可能的耦合的想法。我们证明 δdF 提供了很好的 δF 近似值。具体来说,我们表明 δdF 是 δF 的上限,并且这些度量之间的差异受多边形曲线最长边的长度的限制。我们还表明,可以使用非常简单的算法在 O(pq) 时间内计算 δdF。在这些结果的基础上,以下近似计算两条任意曲线之间的 Fréchet距离的方法不言自明:首先计算曲线的适当多边形近似,然后计算它们的耦合距离,而不是计算它们的精确 Fréchet距离。

Fréchet算法实现

算法的伪代码如下:

在这里插入图片描述

算法的python代码实现如下,参考2

# 部分代码参考:https://github.com/spiros/discrete_frechet

import numpy as np

def frechet_distance_recursion(ca, i, j, p, q):

    if ca[i, j] > -1:
        return ca[i, j]
    elif i == 0 and j == 0:
        ca[i, j] = np.linalg.norm(p[i]-q[j])
    elif i > 0 and j == 0:
        ca[i, j] = max(frechet_distance_recursion(ca, i-1, 0, p, q), np.linalg.norm(p[i]-q[j]))
    elif i == 0 and j > 0:
        ca[i, j] = max(frechet_distance_recursion(ca, 0, j-1, p, q), np.linalg.norm(p[i]-q[j]))
    elif i > 0 and j > 0:
        ca[i, j] = max(
            min(
                frechet_distance_recursion(ca, i-1, j, p, q),
                frechet_distance_recursion(ca, i-1, j-1, p, q),
                frechet_distance_recursion(ca, i, j-1, p, q)
            ),
            np.linalg.norm(p[i]-q[j])
            )
    else:
        ca[i, j] = float('inf')

    return ca[i, j]


def frechet_distance(p, q):
    p = np.array(p, np.float64)
    q = np.array(q, np.float64)

    len_p = len(p)
    len_q = len(q)

    if len_p == 0 or len_q == 0:
        raise ValueError('Input curves are empty.')

    if len_p != len_q or len(p[0]) != len(q[0]):
        raise ValueError('Input curves do not have the same dimensions.')

    ca = (np.ones((len_p, len_q), dtype=np.float64) * -1)

    dist = frechet_distance_recursion(ca, len_p-1, len_q-1, p, q)
    return dist

if __name__=='__main__':
    p=[[1,1], [2,1], [2,2]]
    q=[[2,2], [0,1], [2,4]]
    dist = frechet_distance(p, q)  # 2.0

参考:


  1. Eiter T, Mannila H. Computing discrete Fréchet distance[J]. 1994. ↩︎

  2. GitHub - spiros/discrete_frechet: Compute the Fréchet distance between two polygonal curves in Euclidean space. ↩︎

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KPer_Yang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值