【问题标题】:What is the most efficient way to find the euclidean distance in 3d using mysql?使用mysql在3d中找到欧几里德距离的最有效方法是什么?
【发布时间】:2012-06-12 04:19:13
【问题描述】:

我有一个 MySQL 表,其中存储在 3 列 R、G、B 中的数千个数据点。如何使用欧几里德距离找到最接近给定点 (a,b,c) 的数据点?

我将颜色的 RGB 值分别保存在表格中,因此每列中的值限制为 0-255。我要做的是通过找到欧几里得距离最小的颜色来找到最接近的颜色匹配。

我显然可以遍历表格中的每个点来计算距离,但这不足以有效地进行缩放。有什么想法吗?

【问题讨论】:

标签: php mysql algorithm math euclidean-distance


【解决方案1】:

我认为上述 cmets 都是正确的,但它们 - 在我的拙见中 - 没有回答最初的问题。 (如果我错了纠正我)。所以,让我在这里加上我的 50 美分:

您要求一个 select 语句,假设您的表称为“颜色”,并且您的列称为 r、g 和 b,它们是范围为 0..255 的整数,您正在寻找值,在你的表中,最接近给定值,让我们说:rr,gg,bb,那么我敢尝试以下:

select min(sqrt((rr-r)*(rr-r)+(gg-g)*(gg-g)+(bb-b)*(bb-b))) from colors;

现在,这个答案有很多警告,因为我不确定我的问题是否正确,所以请确认它是否正确,或者纠正我,以便我可以提供帮助。

【讨论】:

  • 嗯?嗯?我放了一些星星来相乘,而不是变成星星,(星号),它使代码斜体,哈哈哈......所以,在(rr-r)(rr-r)的括号之间应该有一个明星。与 (gg-g)(gg-g) 类似,哈哈哈......这是自 1980 年代大型机上的乳胶以来使用的格式化样式! (是的,我是个老家伙)...
  • 感谢您在 SQL 中回答我正在尝试做的问题 - 尽管我想知道这是否会非常有效
【解决方案2】:
  1. 由于您正在寻找最小距离而不是精确距离,您可以跳过平方根。我认为Squared Euclidean Distance 适用于此。
  2. 您已经说过这些值的范围在 0-255 之间,因此您可以创建一个包含 255 个值的索引查找表。

这是我在 SQL 方面的想法。 r0g0b0 代表目标颜色。表Vector 将保存上面#2 中提到的平方值。此解决方案将访问所有记录,但可以通过仅排序和选择第一行将结果集设置为 1。

select 
    c.r, c.g, c.b,
    mR.dist + mG.dist + mB.dist as squared_dist
from 
    colors c,
    vector mR,
    vector mG,
    vector mB
where
    c.r-r0 = mR.point and
    c.g-g0 = mG.point and
    c.b-b0 = mB.point
group by
    c.r, c.g, c.b

【讨论】:

  • 我必须说,我认为你的解决方案是不正确的,user845279...如果你添加 3 个值,那么你会发现,由于数学的交换律(加/加) ,即 10 + 50 + 80 = 140,但 10 + 120 + 10 也是如此,1 + 138 + 1 或 80 + 50 + 10 也是如此。如果你至少使用平方根的距离公式每个平方的分量的总和,那么您将获得一个更好的 3 维空间中的距离公式,包括 XYZ 立方体 (RGB),每个维度的范围在 0 到 255 之间...
【解决方案3】:

我看到你可以做的第一级优化是你想要限制查询的距离的平方,这样你就不需要对每一行执行平方根。 我鼓励的第二级优化是一些预处理,以减轻对每个查询的无关平方的需要(这可能会为大型 RGB 表创建一些额外的运行时间)。您必须进行一些基准测试才能看到,但是通过将值替换为 a、b、c 和 d,然后执行查询,您可以减轻 MySQL 的一些压力。

请注意,最后两行之间的性能差异可以忽略不计。您必须在系统上使用测试查询来确定哪个更快。

我刚刚重新阅读并注意到您是按距离订购的。在这种情况下,应该删除 d 一切都应该移到一侧。您仍然可以插入常量以防止在 MySQL 端进行额外处理。

【讨论】:

    【解决方案4】:

    如果你遍历每个点并计算距离,不要使用平方根函数,没有必要。最小的平方和就足够了。

    这是您要解决的problem。 (平面情况,选择所有按x、y、z轴排序的点。然后用PHP处理)

    MySQL 也有一个Spatial Database,它可能有这个函数。不过我并不乐观。

    【讨论】:

    • 我也在查看最近的一对点问题的维基百科页面,但这是为了将所有点与所有其他点进行比较,以找到每对点之间的最小距离。更不用说我相信您需要根据三个维度中的两个维度进行排序,并且排序会影响效率。此外,虽然我没有使用它,但似乎空间数据库只处理二维点。
    【解决方案5】:

    我相信有两种选择。

    您必须按照您所说的那样遍历整个集合,并比较和检查您最初设置为一个不可能的低数字(如 -1)的最大值。这在线性时间内运行,n 次(因为您只是将 1 点与集合中的每个点进行比较,所以它以线性方式缩放)。

    我仍在考虑另一种选择...类似于从输入点开始进行广度优先搜索,直到在搜索点的集合中找到一个点,但这需要更多考虑(我想 3D 空间必须非常密集才能使平均效率更高)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-17
      • 2020-03-09
      相关资源
      最近更新 更多