从set中选择值以匹配目标值的算法?

时间:2010-05-25 16:52:38

标签: algorithm search performance

我有一个固定的常数整数值数组,大约有300个项目(A组)。该算法的目标是从该数组中选择两个数字(X和Y),这些数字符合基于输入 R 的多个标准。

正式要求:
从集合 A 中选择值 X Y ,使表达式 X * Y /(X + Y)为尽可能接近 R

这就是它的全部。我需要一个简单的算法来做到这一点。

其他信息:
Set A可以以任何方式进行排序或存储,最终将进行硬编码。此外,通过一些数学计算,可以证明给定 X 的最佳 Y 是Set A 中最接近的值表达式 X * R /(XR)。此外, X Y 将始终大于 R

由此,我得到了一个简单的迭代算法,可以正常工作:

int minX = 100000000;
int minY = 100000000;
foreach X in A
    if(X<=R)
        continue;
    else
        Y=X*R/(X-R)
        Y=FindNearestIn(A, Y);//do search to find closest useable Y value in A
        if( X*Y/(X+Y) < minX*minY/(minX+minY) )
        then
            minX = X;
            minY = Y;
        end
    end
end

我正在寻找比这种蛮力方法更优雅的方法。建议?

3 个答案:

答案 0 :(得分:7)

对于可能“更优雅”的解决方案,请参阅解决方案2.


解决方案1)

为什么不创建R的所有可能的300 * 300/2或(300 * 299/2)个可能的精确值,将它们排序为数组B说,然后给出一个R,使用二分搜索在B中找到与R最接近的值,然后选择相应的X和Y.

我认为拥有数组B(带有X&amp; Y信息)不会是一个很大的内存占用,并且很容易被硬编码(使用代码编写代码!: - ))。

这将相当快:最坏情况~17次比较。


解决方案2)

您也可以执行以下操作(未尝试证明,但似乎正确):

维护一个1 / X值的数组,已排序。

现在给出一个R,你试着在1 / X数组中用两个数字找到最接近1 / R的和。

为此你保持两个指向1 / X数组的指针,一个指向最小值,一个指向最大值,并保持递增1并递减另一个以找到最接近1 / R的指针。 (这是一个经典的访谈问题:查找排序数组是否有两个数字总和为X)

在最坏的情况下,这将是O(n)比较和添加。这也容易出现精确问题。但是,您可以通过维护反向排序的X数组来避免一些精度问题。

答案 1 :(得分:1)

我想到了两个想法:

1)由于集合A是常数,因此一些预处理可能会有所帮助。假设A的值跨度不是太大,您可以创建一个大小为N = max(A)的数组。对于每个索引i,您可以将最接近的值存储在A到i中。这样,您可以通过在恒定时间内找到最接近的值来改进算法,而不是使用二进制搜索。

2)我看到你省略了X&lt; = R,这是正确的。如果您定义X <= Y,则可以进一步限制搜索范围,因为X> 2R也不会产生任何解决方案。因此,要扫描的范围是R&lt; X&lt; = 2R,这保证没有对称解,并且X <= Y。

答案 2 :(得分:0)

当输入的大小(大致)恒定时,O(n * log(n))解决方案可能比特定的O(n)解决方案运行得更快。

我会从您理解最佳的解决方案开始,并在需要时从那里进行优化。