Java:距离度量算法设计

Java:距离度量算法设计,java,algorithm,measure,Java,Algorithm,Measure,我正试图用Java解决以下问题(尽管几乎可以用任何其他语言完成): 我得到两个整数值数组,xs和ys,表示x轴上的数据点。它们的长度可能不相同,但都大于0,并且不需要排序。我想计算的是两组数据点之间的最小距离度量。我的意思是,对于每个x,我在ys集合中找到最近的y,并计算距离,例如(x-y)^2。例如: xs = [1,5] ys = [10,4,2] 应返回(1-2)^2+(5-4)^2+(5-10)^2 距离测量并不重要,我感兴趣的是算法。我在考虑对这两个数组进行排序,并以某种方式提升这两

我正试图用Java解决以下问题(尽管几乎可以用任何其他语言完成):

我得到两个整数值数组,
xs
ys
,表示x轴上的数据点。它们的长度可能不相同,但都大于0,并且不需要排序。我想计算的是两组数据点之间的最小距离度量。我的意思是,对于每个
x
,我在
ys
集合中找到最近的
y
,并计算距离,例如
(x-y)^2
。例如:

xs = [1,5]
ys = [10,4,2]
应返回(1-2)^2+(5-4)^2+(5-10)^2

距离测量并不重要,我感兴趣的是算法。我在考虑对这两个数组进行排序,并以某种方式提升这两个数组中的索引,以获得比bruteforce更好的结果(对于x中的每个元素,扫描ys中的所有元素以找到min),即
O(len1*len2)


这是我自己的问题,不是家庭作业问题。非常感谢您的所有提示。

您提出的想法听起来不错。您可以在O(n logn)时间内对列表进行排序。然后,您可以使用另一个列表上的滑动索引在较长的列表上进行一次迭代,以找到“对”。当您在较长的列表中前进时,您将永远不必回溯其他列表。所以现在你的整个算法是O(nlogn+n)=O(nlogn)。

你提出的想法听起来不错。您可以在O(n logn)时间内对列表进行排序。然后,您可以使用另一个列表上的滑动索引在较长的列表上进行一次迭代,以找到“对”。当您在较长的列表中前进时,您将永远不必回溯其他列表。因此,现在您的整个算法是O(nlogn+n)=O(nlogn)。

您的方法非常好,并且具有
O(n1*log(n1)+n2*log(n2))
时间复杂度

如果阵列长度不同,另一种方法是:

  • 对较短的数组进行排序
  • 从头到尾遍历较长的数组,使用二进制搜索查找排序后的短数组中最近的项

  • 这具有
    O((n1+n2)*log(n1))
    时间复杂度,其中
    n1
    是较短数组的长度。

    您的方法非常好,并且具有
    O(n1*log(n1)+n2*log(n2))
    时间复杂度

    如果阵列长度不同,另一种方法是:

  • 对较短的数组进行排序
  • 从头到尾遍历较长的数组,使用二进制搜索查找排序后的短数组中最近的项

  • 这有时间复杂度,
    O((n1+n2)*log(n1))
    其中
    n1
    是较短数组的长度。

    我假设HighPerformanceMark(对您的问题的第一个评论)是正确的,您实际上使用较大的数组,为每个元素找到较小数组中最近的一个,并在这些距离上求和一些f(dist)

    我建议你的做法:

    Sort both arrays 
    indexSmall=0 
    
    // sum up
    for all elements e in bigArray {
      // increase index as long as we get "closer"
      while (dist(e,smallArray(indexSmall)) > dist(e,smallArray(indexSmall+1)) {
        indexSmall++
      }
      sum += f(dist(e,smallArray(indexSmall)));
    }
    

    这是排序的
    O(max(len1,len2)*log(max(len1,len2))
    。其余部分与较大的数组长度成线性关系。现在
    dist(x,y)
    类似于
    abs(x-y)
    ,和
    f(d)=d^2
    或任何你想要的东西。

    我假设HighPerformanceMark(对你的问题的第一个评论)是正确的,你实际上取了较大的数组,为每个元素找到较小数组中最接近的一个,并求出一些f(dist)在这些距离上

    我建议你的做法:

    Sort both arrays 
    indexSmall=0 
    
    // sum up
    for all elements e in bigArray {
      // increase index as long as we get "closer"
      while (dist(e,smallArray(indexSmall)) > dist(e,smallArray(indexSmall+1)) {
        indexSmall++
      }
      sum += f(dist(e,smallArray(indexSmall)));
    }
    

    这是排序的
    O(max(len1,len2)*log(max(len1,len2))
    。其余部分与较大的数组长度成线性关系。现在
    dist(x,y)
    类似于
    abs(x-y)
    ,和
    f(d)=d^2
    或任何你想要的东西。

    在你的例子中,它实际上看起来好像对于每个
    y
    你都能找到最接近的
    x
    ——你可能的意思是,对于较大集合中的每个元素,你都能找到较小集合中最接近的元素,因为你似乎期望在距离计算中有和大集合中元素一样多的项。是的,我比较了大集合和小集合。有没有办法让它比O(len1*len2)更好?在你的例子中,它实际上看起来好像对于每个
    y
    你都能找到最接近的
    x
    ——你的意思可能是,对于较大集合中的每个元素,你都能找到较小集合中最接近的元素,因为你似乎期望在距离计算中有和大集合中元素一样多的项。是的,我比较了大集合和小集合。你知道如何使它比O(len1*len2)更好吗?你需要确保
    indexSmall+1
    不会过度索引
    smallArray
    当然,这只是伪代码。。。但这对实现者来说是一个有用的提示…;)您需要确保
    indexSmall+1
    不会过度索引
    smallArray
    当然,这只是伪代码。。。但这对实现者来说是一个有用的提示…;)