我的扩展欧几里得算法(python)出了什么问题?

时间:2013-06-02 19:13:56

标签: python algorithm math

我找到两个数字的HCF的算法,显示r = a*aqr + b*bqr形式的理由,只是部分有效,即使我很确定我输入了所有正确的公式 - 基本上,它可以并且会找到HCF,但我也试图提供Bezout引理的演示,所以我需要显示上述显示的理由。该计划:

# twonumbers.py
inp = 0
a = 0
b = 0
mul = 0
s = 1
r = 1
q = 0
res = 0
aqc = 1
bqc = 0
aqd = 0
bqd = 1
aqr = 0
bqr = 0
res = 0
temp = 0
fin_hcf = 0
fin_lcd = 0
seq = []
inp = input('Please enter the first number, "a":\n')
a = inp
inp = input('Please enter the second number, "b":\n')
b = inp
mul = a * b # Will come in handy later!
if a < b:
    print 'As you have entered the first number as smaller than the second, the program will swap a and b before proceeding.'
    temp = a
    a = b
    b = temp
else:
    print 'As the inputted value a is larger than or equal to b, the program has not swapped the values a and b.'
print 'Thank you. The program will now compute the HCF and simultaneously demonstrate Bezout\'s Lemma.'
print `a`+' = ('+`aqc`+' x '+`a`+') + ('+`bqc`+' x '+`b`+').'
print `b`+' = ('+`aqd`+' x '+`a`+') + ('+`bqd`+' x '+`b`+').'
seq.append(a)
seq.append(b)
c = a
d = b
while r != 0:
    if s != 1:
        c = seq[s-1]
        d = seq[s]
    res = divmod(c,d)
    q = res[0]
    r = res[1]
    aqr = aqc - (q * aqd)#These two lines are the main part of the justification
    bqr = bqc - (q * aqd)#-/
    print `r`+' = ('+`aqr`+' x '+`a`+') + ('+`bqr`+' x '+`b`+').'
    aqd = aqr
    bqd = bqr
    aqc = aqd
    bqc = bqd
    s = s + 1
    seq.append(r)
fin_hcf = seq[-2] # Finally, the HCF.
fin_lcd = mul / fin_hcf
print 'Using Euclid\'s Algorithm, we have now found the HCF of '+`a`+' and '+`b`+': it is '+`fin_hcf`+'.'
print 'We can now also find the LCD (LCM) of '+`a`+' and '+`b`+' using the following method:'
print `a`+' x '+`b`+' = '+`mul`+';'
print `mul`+' / '+`fin_hcf`+' (the HCF) = '+`fin_lcd`+'.'
print 'So, to conclude, the HCF of '+`a`+' and '+`b`+' is '+`fin_hcf`+' and the LCD (LCM) of '+`a`+' and '+`b`+' is '+`fin_lcd`+'.'

如果你能帮助我找出这个问题,我将不胜感激。

3 个答案:

答案 0 :(得分:8)

嗯,你的程序相当冗长,因此难以阅读。例如,您不需要在前几行中初始化大量这些变量。并且无需分配inp变量,然后将其复制到a然后b。并且您根本不使用seq列表或s变量。

无论如何,这不是问题。有两个错误。我认为如果你把印刷的中间答案与手工制作的例子进行比较,你应该找到问题。

第一个问题是你在第二行有一个拼写错误:

aqr = aqc - (q * aqd)#These two lines are the main part of the justification
bqr = bqc - (q * aqd)#-/

在第二行,aqd应为bqd

第二个问题是在这段代码中

aqd = aqr
bqd = bqr
aqc = aqd
bqc = bqd

您将aqd设为aqr,然后aqc设为aqd。因此,aqcaqd最终会相同。而您实际上想要以其他顺序进行分配:

aqc = aqd
bqc = bqd
aqd = aqr
bqd = bqr

然后代码有效。但我更愿意看到它写得更像这样,我认为更清楚。我遗漏了打印件,但我相信你可以把它们加回来:

a = input('Please enter the first number, "a":\n')
b = input('Please enter the second number, "b":\n')
if a < b:
    a,b = b,a

r1,r2 = a,b
s1,s2 = 1,0
t1,t2 = 0,1
while r2 > 0:
    q,r = divmod(r1,r2)
    r1,r2 = r2,r
    s1,s2 = s2,s1 - q * s2
    t1,t2 = t2,t1 - q * t2

print r1,s1,t1

最后,我认为可能值得查看一个表达解决方案结构的递归版本。

希望这有帮助。

答案 1 :(得分:1)

以下是Bezout身份的简单版本;给定 a b ,它返回 x y g = gcd ( a b ):

function bezout(a, b)
    if b == 0
        return 1, 0, a
    else
        q, r := divide(a, b)
        x, y, g := bezout(b, r)
        return y, x - q * y, g

divide函数返回商和余数。

答案 2 :(得分:0)

执行你想要的python程序(请注意,扩展的Euclid算法只提供一对Bezout系数)可能是:

import sys

def egcd(a, b):
    if a == 0:
        return (b, 0, 1)
    g, y, x = egcd(b % a, a)
    return (g, x - (b // a) * y, y)

def main():
    if len(sys.argv) != 3:
        's program caluclates LCF, LCM and Bezout identity of two integers
        usage %s a b''' % (sys.argv[0], sys.argv[0])
        sys.exit(1)

    a = int(sys.argv[1])
    b = int(sys.argv[2])

    g, x, y = egcd(a, b)

    print 'HCF =',  g
    print 'LCM =', a*b/g
    print 'Bezout identity:  %i * (%i) + %i * (%i)  = %i' % (a, x, b, y, g)

main()