简体   繁体   English

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

[英]Algorithm for finding max value of functions of the form f(x) = a*min(b, x)?

I have an array of tuples (a, b) with a > 0 and b > 0 .我有一个元组(a, b)数组,其中a > 0b > 0
Each tuple represents a function f such that f(x, a, b) = a * min(b, x) .每个元组代表一个 function f使得f(x, a, b) = a * min(b, x)

Is there a known algorithm for a given x to find which tuple returns the maximum value?对于给定的x是否有已知的算法来查找哪个元组返回最大值?
I don't want to evaluate each function to check the maximum, because I will query this array arbitrary number of times for different x .我不想评估每个 function 来检查最大值,因为我会针对不同的x查询这个数组任意次数。

Example:例子:

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)

So the problem is that these tuples can be either sorted by a or by b .所以问题是这些元组可以按ab排序。 But there can be a lot of intersection points between them (if we visualize them as graphs).但是它们之间可能有很多交叉点(如果我们将它们可视化为图形)。 So I want to avoid any O(n^2) sorting algorithm to check for certain ranges of x which is the best function.所以我想避免任何 O(n^2) 排序算法来检查x的某些范围,这是最好的 function。 I mean I don't want to compare each function with all the others to find from which point x' (intersection point) and on I should choose one over the other.我的意思是我不想将每个 function 与所有其他人进行比较,以找到从哪个点x' (交点)开始,我应该选择一个。

Assuming a 's, b 's and queried x 's are always nonnegative, each query can be done in O(log(n)) time after an O(n*log(n)) preprocessing step:假设ab和查询的x总是非负数,每个查询可以在O(n*log(n)) O(log(n))时间内完成:

The preprocessing step eliminates such functions that are strictly dominated by others.预处理步骤消除了严格受他人支配的此类功能。 For example, (5, 10) is larger than (1, 1) for every x.例如,对于每个 x, (5, 10)都大于(1, 1) (So, if there is (5, 10) in the array, then we can remove (1, 1) because it will never be the maximum for any x.) (因此,如果数组中有(5, 10) ,那么我们可以删除(1, 1)因为它永远不会是任何 x 的最大值。)

Here is the general condition: A function (a, b) is larger than (c, d) for every x if and only if c > a and (c*d > a*b) .这是一般条件:当且仅当c > a(c*d > a*b)时,对于每个 x,A function (a, b)大于(c, d) ) 。 (This is easy to prove.) (这很容易证明。)

Now, what we want to do is to remove such functions (a, b) for which there exists a (c, d) such that c > a and (c*d > a*b) .现在,我们要做的是删除存在 a (c, d)的函数(a, b)使得c > a(c*d > a*b) This can be done in O(n*log(n)) time:这可以在 O(n*log(n)) 时间内完成:

1 - Sort tuples lexicographically. 1 - 按字典顺序对元组进行排序。 What I mean by lexicographically is first compare their first coordinates, and if they are equal, then compare the second ones.我的意思是按字典顺序首先比较它们的第一个坐标,如果它们相等,然后比较第二个坐标。 For example, a sorted array might look like this:例如,排序后的数组可能如下所示:

(1, 5)
(1, 17)
(2, 9)
(4, 3)
(4, 4)

2 - Iterate over the sorted array in the reverse order and keep track of the largest value of a*b that you encountered so far. 2 - 以相反的顺序遍历已排序的数组,并跟踪到目前为止您遇到的a*b的最大值。 Let's call this value M .我们称这个值M Now, assume the element that we are processing in the loop is (a, b) .现在,假设我们在循环中处理的元素是(a, b) If a*b < M , we remove this element.如果a*b < M ,我们删除这个元素。 Because for some (c, d) that we processed earlier, both c > a and c*d > a*b , and thus (a, b) is useless.因为对于我们之前处理的一些(c, d)c > ac*d > a*b ,因此(a, b)是无用的。 After this step, the example array will become:在这一步之后,示例数组将变为:

(2, 9)
(4, 4)

(4, 3) was deleted because it was dominated by (4, 4) . (4, 3)被删除,因为它被(4, 4)支配。 (1, 17) and (1, 5) were deleted because they are dominated by (2, 9) . (1, 17)(1, 5)被删除,因为它们由(2, 9)支配。

Once we get rid of all the functions that are never the maximum for any x, the graph of the remaining ones will look like this .一旦我们去掉了所有对于任何 x 都不是最大值的函数,剩下的函数的图形将如下所示

As seen in the graph, every function is the maximum from the point where it intersects with the one before to the point where it intersects with the one after.如图所示,每个 function 是从与前一个相交的点到与后一个相交的点的最大值。 For the example above, (4, 4) and (2, 9) intersect at x = 8 .对于上面的示例, (4, 4)(2, 9)x = 8处相交。 So (4, 4) is the maximum until x = 8 , and after that point, (2, 9) is the maximum.所以(4, 4)是最大值,直到x = 8 ,在那之后, (2, 9)是最大值。 We want to calculate the points where consecutive functions in the array intersect, so that for a given x, we can binary-search on these points to find which function returns the maximum value.我们想计算数组中连续函数相交的点,这样对于给定的 x,我们可以对这些点进行二分搜索,以找到 function 返回的最大值。

The key to efficiency is to avoid useless work.效率的关键是避免无用的工作。 If you imagine a decision tree, pruning branches is a term often used for that.如果您想象一棵决策树,那么修剪分支是一个经常用于此的术语。

For your case, the decision-making is based on choosing between two functions (or tuples of parameters).对于您的情况,决策基于在两个函数(或参数元组)之间进行选择。 In order to select either of the two functions, you just determine the value x at which they give you the same value.为了 select 这两个函数中的任何一个,您只需确定它们为您提供相同值的值x One of them performs better for smaller values, one for larger values.其中一个对于较小的值表现更好,一个对于较大的值。 Also, don't forget this part, it may be that one function always performs better than the other.另外,不要忘记这部分,可能一个 function总是比另一个表现更好。 In that case, the one performing worse can be removed completely (see also above, avoiding useless work.).在这种情况下,可以完全删除表现较差的那个(另见上文,避免无用的工作。)。

Using this approach, you can map from this switchover point to the function on the left.使用这种方法,您可以将 map 从这个切换点切换到左侧的 function。 Finding the optimal function for an arbitrary value just requires finding the next higher switchover point.找到任意值的最佳 function 只需要找到下一个更高的切换点。

BTW: Make sure you have unit tests in place.顺便说一句:确保你有单元测试。 These things are fiddly, especially with floating point values and rounding errors, so you want to make sure that you can just run a growing suite of tests to make sure that one small bugfix didn't break things elsewhere.这些东西很繁琐,尤其是浮点值和舍入错误,所以你要确保你可以运行越来越多的测试套件,以确保一个小错误修复不会破坏其他地方的东西。

I think you should sort array based on 'b' first and then 'a'.我认为您应该先根据“b”对数组进行排序,然后再根据“a”对数组进行排序。 Now for every x just use binary search and find the position from which min(b,x) will give either only b or x depending on value.现在对于每个 x 只需使用二进制搜索并找到 position 从中 min(b,x) 将根据值仅给出 b 或 x。 So from that point if x is small then all the upcoming value of b then take tuple as t1 and and you can count value using that function and for the value of b which will be less than x you compulsorily need traverse.因此,从那时起,如果 x 很小,那么 b 的所有即将到来的值然后将元组作为 t1 并且您可以使用该 function 和 b 的值来计算值,该值将小于 x 您必须遍历。 I'm not sure but that's what I can think.我不确定,但这就是我能想到的。

After pre-processing the data, it's possible to calculate this maximum value in time O(log(n)) , where n is the number of tuples (a, b) .预处理数据后,可以在O(log(n))时间内计算出这个最大值,其中n是元组的数量(a, b)

First, let's look at a slightly simpler question: You have a list of pairs (c, b) , and you want to find the one with the largest value of c , subject to the condition that b<=x , and you want to do this many times for different values of x .首先,让我们看一个稍微简单的问题:您有一个对(c, b)的列表,并且您想要找到具有最大值的一对c ,条件是b<=x ,并且您想要为不同的x值多次执行此操作。 For example, the following list:例如,以下列表:

 c   b
------
11  16
 8  12
 2   6
 7   9
 6  13
 4   5

With this list, if you ask with x=10 , the available values of c are 2, 7 and 4, and the maximum is 7.有了这个列表,如果你用x=10询问, c的可用值为 2、7 和 4,最大值为 7。

Let's sort the list by b :让我们按b对列表进行排序:

 c   b
------
 4   5
 2   6
 7   9
 8  12
 6  13
11  16

Of course, some values in this list can never give an answer.当然,这个列表中的某些值永远无法给出答案。 For example, we can never use the b=2 , c=6 row in an answer, because if 6<=x then 5<=x , so we can use the c=4 row to get a better answer.例如,我们永远不能在答案中使用b=2 , c=6行,因为如果6<=x5<=x ,所以我们可以使用c=4行来获得更好的答案。 So we might as well get rid of pairs like that in the list, ie all pairs for which the value of c is not the highest so far.所以我们不妨去掉列表中类似的对,即所有c的值不是迄今为止最高的对。 So we whittle the list down to this:因此,我们将列表缩减为:

 c   b
------
 4   5
 7   9
 8  12
11  16

Given this list, with an index on b , it's easy to find the highest value of c .鉴于此列表,在b上有一个索引,很容易找到c的最大值。 All you have to do is find the highest value of b in the list which is <=x , then return the corresponding value of c .您所要做的就是在列表中找到b的最大值<=x ,然后返回c的对应值。

Obviously, if you change the question so that you only want the values with b>=x (instead of b<=x ), you can do exactly the same thing.显然,如果您更改问题以便只需要b>=x (而不是b<=x )的值,您可以做完全相同的事情。

Right.正确的。 So how does this help with the question you asked?那么这对您提出的问题有何帮助?

For a given value of x , you can split the question into 2 questions.对于给定的x值,您可以将问题分成 2 个问题。 If you can answer both of these questions then you can answer the overall question:如果你能回答这两个问题,那么你就可以回答整体问题:

  1. Of the pairs (a, b) with b<=x , which one gives the highest value of f(x,a,b) = a*b ?b<=x(a, b)对中,哪一个给出f(x,a,b) = a*b的最高值?
  2. Of the pairs (a, b) with b>=x , which one gives the highest value of f(x,a,b) = a*x ?b>=x的对(a, b)中,哪一个给出f(x,a,b) = a*x的最高值?

For (1), simply let c=a*b for each pair and then go through the whole indexing rigmarole outlined above.对于 (1),简单地让每对c=a*b ,然后通过上面概述的整个索引复杂性让 go。

For (2), let c=a and do the indexing thing above, but flipped round to do b>=x instead of b<=x ;对于(2),让c=a并执行上面的索引操作,但翻转以执行b>=x而不是b<=x when you get your answer for a , don't forget to multiply it by x .当你得到a的答案时,不要忘记将它乘以x

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 以 |xa| 形式查询多个方程在 x 处的最小值 + b - Query min value at x of many equations in the form |x-a| + b 是否可以微观优化“x = max(a,b); y = min(a,b);“? - Is it possible to micro-optimize “x = max(a,b); y = min(a,b);”? 在Java算法中需要帮助以找到最大值和最小值 - Need help in java algorithm for finding max and min 求最大值的最优算法 - Optimal algorithm for finding max value 专家:根据限制(最小x最大)预测数字键盘中下一个键的算法 - Expert: algorithm to predict next key in a numeric keyboard based on limits (min x max) 算法,在给定的最小值和最大值之间找到“数字不除以平方数” - Algorithm, finding “number not divided by square numbers” between given min and max value 如何优化一个算法,该算法返回正整数x的值,使得部分已知函数的f(x)&gt; = 0? - How to optimize an algorithm that returns the value of a positive integer x such that f(x) >=0 for a partially known function? 如何使用最小/最大的行拖曳算法? F# - How to use a line draiwng algorithm with min/max? F# 查找最大/最小连续XOR值 - Finding Max/Min Consecutive XOR value Hill Climbing算法在图中寻找局部最小值/最大值的时间复杂度 - Time complexity of Hill Climbing algorithm for finding local min/max in a graph
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM