设f是在非负整数n≥0上定义的函数。假设f已知为U形(凸起并最终增大)。如何找到它的最低限度?也就是说,m使得所有n的f(m)≤f(n)。
U形函数的例子:
当然,人类数学家可以尝试使用微积分来最小化这些特定函数。但是对于我的电脑,我想要一种可以最小化任何U形函数的通用搜索算法。
这些函数在Python中再次帮助任何想要测试算法的人。
f = lambda n: n**2 - 1000*n + 100
g = lambda n: sum(1/i for i in range(1,n+1)) + 1000/sqrt(1+n)
在答案中不一定需要代码(任何语言),只需要算法的描述。我会感兴趣的是看看这些特定功能的答案。
答案 0 :(得分:2)
您可能正在寻找ternary search
三元搜索有助于在f(m)
时间内找到O(logN)
作为您的要求,其中N
是曲线上的点数。
它基本上在范围(l,r)
中取两个点m1和m2,然后在1/3 rd
部分中递归搜索。
python中的代码(来自维基百科):
def ternarySearch(f, left, right, absolutePrecision):
while True:
#left and right are the current bounds; the maximum is between them
if abs(right - left) < absolutePrecision:
return (left + right)/2
leftThird = (2*left + right)/3
rightThird = (left + 2*right)/3
if f(leftThird) < f(rightThird):
right = rightThird
else:
left = leftThird
答案 1 :(得分:0)
如果已知您的函数是单峰的,请使用斐波那契搜索。 http://en.wikipedia.org/wiki/Fibonacci_search_technique
对于离散域,决定新的&#34;测试点的位置&#34;被探测的必须稍微调整,因为连续域的公式不会产生整数。无论如何,工作原则仍然存在。
关于所需的测试数量,我们有以下层次结构:
#Fibonacci < #Golden < #Ternary < #Dichotomic
答案 2 :(得分:0)
这也有效。在导数上使用二进制搜索以最大化f'<= 0
def minimise_convex(f):
"""Given a U-shaped (convex and eventually increasing) function f, find its minimum over the non-negative integers. That is m such that f(m) <= f(n) for all n. If there exist multiple solutions, return the largest. Uses binary search on the derivative."""
f_prime = lambda n: (f(n) - f(n-1)) if n > 0 else 0
return binary_search(f_prime, 0)
定义二进制搜索
def binary_search(f, t):
"""Given an increasing function f, find the greatest non-negative integer n such that f(n) <= t. If f(n) > t for all n, return None."""