algorithm – 确定数字是否满足欠定方程

理论上可以用O(1)空间和时间复杂度来确定一个已知的正整数K是否是方程的解

《algorithm – 确定数字是否满足欠定方程》

其中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
点赞