My task is to use a binary search to write a method optimal() that finds the max value of a function of unsigned ints. The domain of the function is 0 to 2^64 - 1. I know no information about the max value or the max index. The only information I have is a method, double func(unsigned int x); which returns the value of x at the max. I also know that the function is either strictly increasing, strictly decreasing, or increasing to a point, then decreasing.
我的任务是使用二进制搜索编写一个Optimal()方法,该方法查找无符号整数的函数的最大值。函数的域是0到2^64-1。我不知道有关最大值或最大索引的信息。我所拥有的唯一信息是一个方法,Double Func(无符号整型x);它返回最大值时的x的值。我还知道,函数要么严格增加,要么严格减少,要么增加到某一点,然后减少。
I attempted to check for strictly increasing functions:
我尝试检查是否有严格递增的函数:
unsigned int optimal()
{
unsigned int x, y, mid, size, start;
size = 2e32 - 1;
start = 0;
x = 1;
y = size - 1;
if ((func(start) < func(x)) && (func(y) < func(size))) return size;
if ((func(start) > func(x)) && (func(y) > func(size))) return start;
return 0;
}
which didn't work.
但这并不管用。
更多回答
Is func(2^64 - 2)
pseudo-code, or is that what you had in your code? (Hard to know, since you did not provide your actual code.)
Func(2^64-2)是伪代码吗,或者您的代码中就有这样的代码?(很难知道,因为您没有提供实际代码。)
A minimun reproduction code/repo would help us find out your coding problems
最小复制代码/repo将帮助我们找出您的编码问题
@Eljay it's psuedocode, I didn't provide my actual code because all I had actually written were attempts to check for a strictly decreasing or increasing function, which didn't work
@Eljay这是伪代码,我没有提供我的实际代码,因为我实际编写的所有代码都是尝试检查严格递减或递增的函数,但这不起作用
Your if statement logic seems to be incorrect, it should be if (func(0) > func(1)) then returns func(0)
for decreasing function else if (func(2^64 - 2) < func(2^64 - 1)) then returns func(2^64 - 1)
for increasing function
您的IF语句逻辑似乎不正确,它应该是IF(func(0)>func(1)),则对于递减函数返回func(0);对于递增函数,if(func(2^64-2)
优秀答案推荐
Looks like the function seems to be an increasing/decreasing/increasing-then-decreasing array once you spread the input number out in array from 0 to n. You can use binary search to find the peak in the function. For each mid point, you can determine if the part of the array is decreasing, increasing or peak and then locate which part of the array likely to have the peak. You can find more details and explanation in this article
当您将数组中的输入数字从0扩展到n时,该函数看起来就像是一个increasing/decreasing/increasing-then-decreasing数组。您可以使用二进制搜索来查找函数中的峰值。对于每个中点,您可以确定阵列的部分是减少、增加还是达到峰值,然后定位阵列的哪个部分可能具有峰值。您可以在这篇文章中找到更多详细信息和解释
int maxInBitonic(int arr[], int low, int high)
{
// find out the size of the array
// for edge case checking
int n = high + 1;
// main code goes as follows
while (low <= high) {
// find out the mid
int mid = low + (high - low) / 2;
// if mid index value is maximum
if(arr[mid] > arr[mid+1] and arr[mid] > arr[mid-1])
return arr[mid];
// reducing search space by moving to right
else if (arr[mid] < arr[mid + 1])
low = mid + 1;
// reducing search space by moving to left
else
high = mid - 1;
}
return arr[high];
}
Unfortunately I am unfamiliar with C++ to assist you in code, but these points might help.
不幸的是,我不熟悉C++来帮助您编写代码,但这些要点可能会有所帮助。
What about checking for the gradient of the function and moving in the same direction. Since your function (as you describe it) only have one maximal point, I think this is the correct approach.
Gradient calculation: grad(x1 - x2) = (f(x1) - f(x2))/ (x1 - x2)
Apply Binary search to restrict the search domain. So if you check the gradient between 0
and 1
and it's positive for example. Then we move to the right side along the gradient since we know the function is increasing moving to the side of 1
. Then we move our search to between 1
and 2^64 - 1
, cutting the search domain in half. Rinse and repeat.
So if we keep doing this, at some point we either hit gradient of 0 or very small gradient value (~0
), and even your gradient value can be oscillating between negative and positive, meaning you are close to a local max/min (but in our function's case, it is a max). Here you can manually tweak your search to more quickly converge to that final result if needed. Or just decide to stop on a estimated value.
But since you're doing binary search, i think it will converge quickly anyways. Step 4 is usually needed in gradient decend where we have no idea about the domain size. This case however, there is a domain size and binary search is good fit.
Hope this help, good luck with your work!
希望这对你有所帮助,祝你工作顺利!
更多回答
Thank you! This system worked perfectly.
谢谢!这个系统运行得非常完美。
What information does a gradient calculation between 0 and 1 give me that a simple check of f(0) and f(1) does not? Also, how does restricting my size by 1 value cut my search domain in half?
在0和1之间的梯度计算给我提供了什么信息,而简单地检查f(0)和f(1)不能?另外,将我的大小限制为1值如何将我的搜索域减半?
Ah yes I guess you're correct, gradient value is only valid as a "velocity" in gradient decend method, it gives you how fast your function is increasing/decreasing so that we can move along it. So in our case of binary search it is not very do much compare to simple function value check. As for search domain, I'm saying that if the function is increasing, check the right side instead of the left side, which cuts the domain in half.
啊,是的,我想你是对的,梯度值只有在梯度下降法中才是有效的“速度”,它告诉你你的函数增加/减少的速度,这样我们就可以沿着它移动了。因此,在我们的二进制搜索的情况下,与简单的函数值检查相比,这并不是很有效。至于搜索域,我的意思是,如果功能在增加,检查右侧而不是左侧,这会将域一分为二。
我是一名优秀的程序员,十分优秀!