如何最小化已知为U形的整数函数?

时间:2014-04-13 12:45:32

标签: algorithm math mathematical-optimization

设f是在非负整数n≥0上定义的函数。假设f已知为U形(凸起并最终增大)。如何找到它的最低限度?也就是说,m使得所有n的f(m)≤f(n)。

U形函数的例子:

  • n ** 2 - 1000 * n + 100
  • (1 + 1/2 + ... + 1 / n)+ 1000 / sqrt(1 + n)

当然,人类数学家可以尝试使用微积分来最小化这些特定函数。但是对于我的电脑,我想要一种可以最小化任何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)

在答案中不一定需要代码(任何语言),只需要算法的描述。我会感兴趣的是看看这些特定功能的答案。

3 个答案:

答案 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."""