我需要找到A X 形式的所有单项式,当评估时,它在m
到n
的范围内。可以肯定地说,基数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
,但我认为这不会产生严重影响。我也想知道使用对数是否会更好或者是否有一个封闭的表单表达式。我愿意接受任何优化或替代方案来寻找解决方案。
答案 0 :(得分:7)
使用log(x)是递增函数的事实:
m <= a^x <= n
当且仅当log(m) <= x * log(a) <= log(n)
然后找到其产品位于此转换间隔内的数字x
,log(a)
将更容易。
答案 1 :(得分:5)
不要搜索;考虑端点。
例如,x == 3
的所有解决方案都是a
位于m
的多维数据集根目录和n
的多维数据集根目录之间。因此,计算这些立方根并使用其间的整数范围。由于a
至少为2,因此最大x
是n
的对数基数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)