理论上可以用O(1)空间和时间复杂度来确定一个已知的正整数K是否是方程的解
其中a和b是固定的,正整数(既不是另一个的倍数),而μi是未知的非负整数,除了有限数量(但不是全部)都是零之外?如果在O(1)空间和时间中不可能,那么最着名算法的空间和时间要求是多少?
我发现这个问题的唯一方法就是提前列举所有可能的Ks的子集,但当然这要求我选择上截止M和N,使得i≤N且∀μi≤M.更糟糕的是,它的空间要求是O(MN),这可能是如此巨大,以至于没有查找算法在真实硬件上实现O(1)检索性能.我有一种不好的感觉,这实际上是伪装的Knapsack Problem,但我还不确定是否放弃了.
我试图在空间和时间上一直到O(1),因为我需要知道这是否可以在一个嵌入式环境中实时完成,在CPU或RAM中几乎没有任何空间.
我不需要知道满意的μi值集.
编辑:此Python函数计算一个集合对象S,使得S中的K为真,当且仅当K是上述等式的解之一时,给定a,b和如上所述的截止M和N.
def compute_set(a, b, M, N):
ss = [a*i + b for i in xrange(1,N+1)]
aa = itertools.product(xrange(0,M+1), repeat=N)
rv = set(map(lambda a: sum(a[i]*ss[i] for i in xrange(N)), aa))
rv.remove(0)
return rv
最佳答案 分两个阶段解决.
在阶段1中,使用用于处理Diophantine equations的标准技术计算集合{(x,y):x,y在Z中并且ax由= K}的描述.设g = gcd(a,b);除非g除以K,否则没有解决方案.通过extended Euclidean algorithm计算g来解决ax’by’= g以及计算g;第一种解决方案是(x’,y’)* K / g.其他解决方案通过(-b / g,a / g)的整数倍相加.
在阶段2中,计算可以通过不同的μi选择实现的(x,y)解的描述.由于K≥0,我们知道y≥1是必要条件.如果n是变量,那么x≥0且y≥1是必要且充分的条件(将μ0= y-1和μx= 1以及所有其他μs设置为0).
如果n是一个参数,那么事情会有点棘手.使用阶段1的结果,找到x≥0且y最大的解(x,y)(如果没有这样的解,那么K是不可行的).对于此解决方案,请检查x / y是否为n.
def egcd(A, B):
"""Returns a triple (gcd(A, B), s, t) such that s * A + t * B == gcd(A, B)."""
a, b, s, t, u, v = A, B, 1, 0, 0, 1
while True:
assert s * A + t * B == a
assert u * A + v * B == b
if not b:
break
q, r = divmod(a, b)
a, b, s, t, u, v = b, r, u, v, s - q * u, t - q * v
return a, s, t
def solvable(K, a, b):
g, s, t = egcd(a, b)
q, r = divmod(K, g)
if r:
return False
x, y = s * q, t * q
assert a * x + b * y == K
d = a // g
q, r = divmod(y, d)
if r <= 0:
q -= 1
r += d
assert 0 < r <= d
x, y = x + q * (b // g), r
assert a * x + b * y == K
return x >= y