寻找形式为 f(x) = a*min(b, x) 的函数的最大值的算法?

问题描述

我有一组包含 (a,b)a > 0 的元组 b > 0
每个元组代表一个函数 f,使得 f(x,a,b) = a * min(b,x).

对于给定的 x 是否有已知的算法来查找哪个元组返回最大值?
我不想评估每个函数来检查最大值,因为我会针对不同的 x 查询这个数组任意次数。

示例:

array = [ (1,10),(2,3) ]
x < 6 -> choose (2,3)
x = 6 (intersection point) -> either (1,10) or (2,3) doesn't matter
x > 6 -> choose (1,10)

所以问题是这些元组可以按 ab 排序。但是它们之间可能有很多交点(如果我们将它们可视化为图形)。所以我想避免任何 O(n^2) 排序算法来检查 x 的某些范围,这是最好的函数。我的意思是我不想将每个函数与所有其他函数进行比较,以找出我应该从哪个点 x'(交点)和在另一个中选择一个。

解决方法

效率的关键是避免无用的工作。如果你想象一棵决策树,修剪分支是一个常用的术语。

对于您的情况,决策基于在两个函数(或参数元组)之间进行选择。为了选择这两个函数中的任何一个,您只需确定它们为您提供相同值的值 x。其中一种对于较小的值表现更好,另一种对于较大的值。另外,不要忘记这一部分,可能是一个功能总是比另一个表现得更好。在这种情况下,可以完全删除性能较差的那个(另请参见上文,避免无用的工作!)。

使用这种方法,您可以从此切换点映射到左侧的函数。找到任意值的最优函数只需要找到下一个更高的切换点。

顺便说一句:确保你有单元测试。这些事情很繁琐,尤其是浮点值和舍入错误,因此您要确保可以运行不断增长的测试套件,以确保一个小错误修复不会破坏其他地方的事情。

,

我认为您应该先根据 'b' 再根据 'a' 对数组进行排序。现在对于每个 x 只需使用二进制搜索并找到 min(b,x) 将根据值仅给出 b 或 x 的位置。因此,从那时起,如果 x 很小,那么 b 的所有即将到来的值都将元组作为 t1 并且您可以使用该函数计算值,并且对于小于 x 的 b 值,您必须遍历。我不确定,但这是我能想到的。

,

预处理数据后,可以在 O(log(n)) 时间内计算出这个最大值,其中 n 是元组数 (a,b)

首先,让我们看一个稍微简单的问题:您有一个 (c,b) 对的列表,并且您想找到具有最大值 c 的那个,条件是 {{ 1}},并且您想对不同的 b<=x 值执行多次此操作。例如,以下列表:

x

有了这个列表,如果用 c b ------ 11 16 8 12 2 6 7 9 6 13 4 5 查询,x=10的可用值为2、7和4,最大值为7。

让我们按 c 对列表进行排序:

b

当然,此列表中的某些值永远无法给出答案。例如,我们永远不能在答案中使用 c b ------ 4 5 2 6 7 9 8 12 6 13 11 16 ,b=2 行,因为如果 c=6 then 6<=x,所以我们可以使用 5<=x 行来得到更好的答案。因此,我们不妨去掉列表中类似的对,即 c=4 的值目前不是最高的所有对。因此,我们将列表缩减为:

c

给定这个列表,在 c b ------ 4 5 7 9 8 12 11 16 上有一个索引,很容易找到 b 的最大值。您所要做的就是在列表中找到c 的最大值,即b,然后返回<=x 的对应值。

显然,如果您更改问题以便只需要带有 c(而不是 b>=x)的值,您可以做完全相同的事情。

没错。那么这对您提出的问题有何帮助?

对于给定的 b<=x 值,您可以将问题拆分为 2 个问题。如果您能回答这两个问题,那么您就可以回答整个问题:

  1. x(a,b) 对中,哪一个给出了最高的 b<=x 值?
  2. f(x,a,b) = a*b(a,b) 对中,哪一个给出了最高的 b>=x 值?

对于 (1),只需让 f(x,b) = a*x 代表每一对,然后完成上面概述的整个索引繁琐。

对于(2),让 c=a*b 并做上面的索引事情,但翻转过来做 c=a 而不是 b>=x;当您得到 b<=x 的答案时,不要忘记将其乘以 a

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...