在Python中求解三个变量Diophantine方程

时间:2012-09-25 14:20:40

标签: python algorithm diophantine

我是Python的初学者,并尝试使用MIT 6.00,提供的页面是作业页面。

我在assignment 2,在那里我必须找到Diophantine方程的解决方案,我在数学方面真的不是那么好,所以我试着尽可能多地理解它做了什么,并且想一想解决方案。

这就是我所要做的:

def test(x):
    for a in range(1,150):
        for b in range(1,150):
            for c in range(1,150):
                y = 6*a+9*b+20*c
                if y == x:
                    print "this --> " , a, b, c
                    break
                else : ##this to see how close i was to the number
                    if y - x < 3: 
                        print a, b, c , y

该作业指出50, 51, 52, 53, 54, and 55有一个解决方案,但不幸的是,该脚本只能获得50, 53 and 55的解决方案。

如果有人解释我的代码中有什么问题,或者我根本不理解丢番图方程式,我会非常感激,请告诉我它是什么以及如何为它找到解决方案,因为我不能让作业的解释进入我的脑海。

感谢。

9 个答案:

答案 0 :(得分:3)

的解决方案
6*a+9*b+20*c = 51

对于整数abc必须至少有一个整数0或负数。一些解决方案

6*7 + 9*1 + 20*0 = 51
6*0 + 9*(-1) + 20*3 = 51

根据赋值中的约束,您需要在可能的系数中包含0或甚至负数。

答案 1 :(得分:3)

作业说:

确定是否可能 只买n个McNuggets,就得解决一个Diophantine方程:找到非负整数 a,b和c的值,这样 6a + 9b + 20c = n。

您似乎必须在函数范围中包含零。这样,您就可以找到所需数字的解决方案。

答案 2 :(得分:2)

51的解决方案是5*9 + 1*6

提示:20在哪里?这对它的系数意味着什么?

54的解决方案是3*20 + (-1)*6。你弄明白了其余部分。

答案 3 :(得分:1)

首先,您可以有效地利用边界分析。给定

6a + 9b + 20c = n
0 <= a
0 <= b
0 <= c

我们可以系统地将{a,b,c}对设置为0来推断剩余变量的上限。这给了我们

a <= floor(n / 6)
b <= floor(n / 9)
c <= floor(n / 20)

此外,如果你选择一个策略(例如,分配c然后分配b然后a),你可以进一步收紧上限,例如:

b <= floor((n - 20c) / 9)

此外,要分配的最后一个变量必须是其他变量的函数:您不需要搜索它。

答案 4 :(得分:1)

您可以从0到150开始a,b,c的范围。

实际上即使我是初学者也只是从MIt 6.00开始。 在阅读他们的问题时,我认为这是对无法采取的最大数量的限制。

答案 5 :(得分:0)

这是Perl的解决方案。而是使用正则表达式进行攻击。

按照此博客post使用正则表达式求解代数方程式。

我们可以使用以下脚本3x + 2y + 5z = 40

#!/usr/bin/perl
$_ = 'o' x 40;
$a = 'o' x 3;
$b = 'o' x 2;
$c = 'o' x 5;
$_ =~ /^((?:$a)+)((?:$b)+)((?:$c)+)$/;
print "x = ", length($1)/length($a), "\n";
print "y = ", length($2)/length($b), "\n";
print "z = ", length($3)/length($c), "\n";

输出:x = 11,y = 1,z = 1

着名的Oldest plays the piano谜题最终成为一个3变量方程式

此方法适用于condition变量实际为正且常数为正。

答案 6 :(得分:0)

检查我改编自你的那个。它似乎解决了你的问题:

variables=range(0,10)
exams=range(51,56)
for total in exams:
    for a in variables:
        for b in variables:
            for c in variables:
                if total==4*a+6*b+20*c:
                    print a, 'four pieces', b, 'six pieces','and', c ,'twenty pieces', 'for a total of', total

答案 7 :(得分:0)

break函数只会突破最近的循环。下面的代码使用一个指标来突破每个循环。

    n = 1     # n starting from 1
    count = 0 # Count + 1 everytime we find a possible value. 
              # Reset = 0 after a non-possible value. 
    notPossibleValue = ()
    while True:
        ind = 0 # become 1 if int solutions were found
        for c in range (0,n/20+1):
            if ind == 1: break 
            for b in range (0,n/9+1):
                if ind == 1: break 
                for a in range (0, n/6+1):
                    if (n-20*c) == (b*9+a*6):
                        count += 1
                        ind = 1                    
                        # print 'n=', n, a,b,c, 'count', count                       
                        break # Break out of "a" loop
        if ind == 0:
            count = 0
            notPossibleValue += (n,)
            # print notPossibleValue, 'count', count
        if count == 6:
            print 'The largest number of McNuggets that cannot be bought in exact quantity is', notPossibleValue[-1]
            break
        n += 1

答案 8 :(得分:0)

n=1
a=0
b=0
c=0
mcnugget = []
for i in range (n,100):
   for a in range (0,20):
       if  6*a + 9* b +20*c ==i:
           mcnugget.append(i)
           break
       else:
            for b in range (0,12):
                if  6*a + 9* b +20*c ==i:
                    mcnugget.append(i)
                    break
                else:
                    for c in range(0,5):
                        if  6*a + 9* b +20*c ==i:
                            mcnugget.append(i)
                            break
   else:
        if i>8:
            if mcnugget[-1]==mcnugget[-2]+1==mcnugget[-3]+2==mcnugget[-4]+3==mcnugget[-5]+4==mcnugget[-6]+5 and mcnugget[-6]>0 :
                break

mcnugget = set (mcnugget)
mcnugget = list (mcnugget)
count = 0
for z in mcnugget:
   count += 1
   if mcnugget [count]==mcnugget [count-1]+1==mcnugget [count-2]+2==mcnugget [count-3]+3==mcnugget [count-4]+4==mcnugget[count-5]+5:
      biggestN= mcnugget[count-6]
      break
#print (mcnugget)
biggestN = str(biggestN)

print ('Largest number of McNuggets that cannot be bought in exact quantity: <'+ biggestN +'>')