找到给定范围内的所有A ^ x

时间:2012-03-21 23:28:12

标签: python algorithm optimization

我需要找到A X 形式的所有单项式,当评估时,它在mn的范围内。可以肯定地说,基数A大于1,幂X大于2,并且只需要使用整数。例如,在50到100的范围内,解决方案将是:

2^6
3^4
4^3

我首次尝试解决这个问题,就是强行使用“{1}}和A的所有组合”。然而,当在大范围内用于非常大的数字时,这变得太慢,因为这些解决方案在更密集的处理中被使用。这是代码:

X

我可以通过将值保存在临时变量中来删除一个def monoSearch(min, max): base = 2 power = 3 while 1: while base**power < max: if base**power > min: print "Found " + repr(base) + "^" + repr(power) + " = " + repr(base**power) power = power + 1 base = base + 1 power = 3 if base**power > max: break ,但我认为这不会产生严重影响。我也想知道使用对数是否会更好或者是否有一个封闭的表单表达式。我愿意接受任何优化或替代方案来寻找解决方案。

4 个答案:

答案 0 :(得分:7)

使用log(x)是递增函数的事实:

m <= a^x <= n当且仅当log(m) <= x * log(a) <= log(n)

然后找到其产品位于此转换间隔内的数字xlog(a)将更容易。

答案 1 :(得分:5)

不要搜索;考虑端点。

例如,x == 3的所有解决方案都是a位于m的多维数据集根目录和n的多维数据集根目录之间。因此,计算这些立方根并使用其间的整数范围。由于a至少为2,因此最大xn的对数基数2,因此您知道何时停止。

from math import log, ceil, floor

def monoSearch(low, high):
    max_power = int(floor(log(high) / log(2)))
    for power in range(3, max_power + 1):
        min_base = low ** (1.0 / power)
        max_base = high ** (1.0 / power)
        for base in range(int(ceil(min_base)), int(floor(max_base)) + 1):
            yield '%s ^ %s' % (base, power)

print '\n'.join(monoSearch(42, 1000000))

遗憾的是,由于浮点不精确,这可能会遗漏几个值。

答案 2 :(得分:1)

您可以使用多个二进制搜索来优化它。请注意以下任何给定的基础:

  • 一旦达到base**power超过min所有权力p >= power满足base**p >= min - &gt;的权力您可以二进制搜索最小功率
  • 类似的论证证明您可以二进制搜索最大功率,例如base**power <= max
  • 要为base**power <= max找到power >= 3的最大基数,您还可以应用二进制搜索

现在,您可以使用@wim所说的对数,但这要求您使用的数字可以由浮点数表示,而使用二进制搜索只要您有任意精度整数算术(和Python一样)就可以工作。

答案 3 :(得分:1)

您可以使用对数找到工作指数的下限和上限。它基本上找到了最小的指数,以及适合m和n的最大指数,并为此创建了一个范围。如果有任何特别令人困惑的部分(我知道我嵌套了许多功能),那就问问。

from math import log, ceil, floor, sqrt

def monoSearch(m, n):
    for base in range(2, int(ceil(n**.34))):
        m_pow = max(int(ceil(log(m, base))), 3)
        n_pow = int(ceil(log(n, base)))

        pows = range(m_pow, n_pow)
        for p in pows:
            print "Found {}^{}  = {}".format(base, p, base**p)