找到小于数字的最大x ^ y

时间:2012-11-14 13:05:49

标签: algorithm math

我有数字A(从数字0,1,2,3构建)。我想找到最小的x和y,如果我做x ^ y我得到的最大数字小于A

x ^ y< = A x ^ y是最大

加x和y不能是十进制数,只能是"整数"

例如:

A = 7 => x^y = 2^2
A = 28 => x^y = 3^3
A = 33 => x^y = 2^5

修改 正如izomorphius在评论中所建议的那样,它总是能解决x = A和y = 1.但这不是理想的结果。我希望x和y尽可能接近数字。

2 个答案:

答案 0 :(得分:2)

一个天真的解决方案可能是:

对某个常量a^y a执行“最接近但不高于”的数字是:

afloor(log_a(A)) [其中log_a(A)是基数a A的对数,在大多数编程语言中可以计算为log(A)/log(a)]

通过迭代范围a中的所有[2,A),您可以找到此数字。

此解决方案为O(A * f(A)),其中f(A)是您的战略/日志复杂性

PS 如果您希望指数(y)大于1,则可以简单地在范围[2,sqrt(A)]内迭代 - 它会将时间复杂度降低到{{1 - 并且只会获得指数大于1的数字。

答案 1 :(得分:1)

目前尚不清楚你在问什么,但我会猜测。

我们首先为实数z^z = a求解等式z。让uv分别向上和向下舍入z。在三个候选人(u,u)(v,u)(u,v)中,我们选择了不超过a的最大候选人。

示例:构造案例a = 2000。我们通过数值方法(见下文)解决z^z = 2000以获得近似解z = 4.8278228255818725。我们向上舍入以获得u = 4v = 5。我们现在有三个候选人4^4 = 2564^5 = 10235^4 = 625。它们都小于2000,因此我们选择的答案最大,x = 4y = 5

这是Python代码。函数solve_approx可以满足您的需求。它适用于a >= 3。我相信您可以自己处理案例a = 1a = 2

import math

def solve(a):
    """"Solve the equation x^x = a using Newton's method"""
    x = math.log(a) / math.log(math.log(a)) # Initial estimate
    while abs (x ** x - a) > 0.1:
        x = x - (x ** x - a) / (x ** x * (1 + math.log(x)))
    return x

def solve_approx(a):
    """"Find two integer numbers x and y such that x^y is smaller than
    a but as close to it as possible, and try to make x and y as equal
    as possible."""
    # First we solve exactly to find z such that z^z = a
    z = solve(a)
    # We round z up and down
    u = math.floor(z)
    v = math.ceil(z)
    # We now have three possible candidates to choose from:
    # u ** zdwon, v ** u, u ** v
    candidates = [(u, u), (v, u), (u, v)]
    # We filter out those that are too big:
    candidates = [(x,y) for (x,y) in candidates if x ** y <= a]
    # And we select the one that gives the largest result
    candidates.sort(key=(lambda key: key[0] ** key[1]))
    return candidates[-1]

这是一个小小的演示:

 >>> solve_approx(5)
 solve_approx(5)
 (2, 2)
 >>> solve_approx(100)
 solve_approx(100)
 (3, 4)
 >>> solve_approx(200)
 solve_approx(200)
 (3, 4)
 >>> solve_approx(1000)
 solve_approx(1000)
 (5, 4)
 >>> solve_approx(1000000)
 solve_approx(1000000)
 (7, 7)