在MIT公开课《计算机科学与编程导论》的Assignment2中,提到了丢番图方程,并有趣地将丢番图方程和卖麦乐鸡的问题联系到了一起。
首先让我们来看看维基百科中介绍的丢番图方程。
一、丢番图方程
丢番图方程又名不定方程、整系数多项式方程,是变量仅容许是整数的多项式等式;即形式如右上角图的方程,其中所有的aj、bj和c均是整数,若其中能找到一组整数解m1,m2...mn者则称之有整数解。 丢番图问题有数条等式,其数目比未知数的数目少;丢番图问题要求找出对所有等式都成立的整数组合。对丢番图问题的数学研究称为丢番图分析。 3世纪希腊数学家亚历山大城的丢番图曾对这些方程进行研究。 丢番图方程的例子有贝祖等式、勾股定理的整数解、四平方和定理和费马最后定理等
编辑本段丢番图生平
代数之父─丢番图(Diophantine)是一位古希腊的大数学家,为第一位懂得使用符号代表数来研究问题的人。 其中丢番图最著名的可能就是他的墓志铭了: 「坟中安葬着丢番图,多么令人惊讶,它忠实地记录了所经历的道路。 上帝给予的童年占六分之一,又过十二分之一,两颊长胡,再过七分之一,点燃起结婚的蜡烛。 五年之后天赐贵子,可怜迟到的宁馨儿,享年仅及其父之半,便进入冰冷的墓。 悲伤只有用数论的研究去弥补,又过四年,他也走完了人生的旅途。 」 我们可以从中知道:“丢番图的一生,幼年占1/6,青少年占1/12,又过了1/7才结婚,5年后生子,子先父4年而卒,寿为其父之半。”计算丢番图的方程为X/6 + X/12 + X/7 + 5 + X/2 + 4 = X,X = 84,由此知道丢番图享年84岁。二、麦乐鸡销售问题
McDiophantine: Selling McNuggets
In mathematics, a Diophantine equation (named for Diophantus of Alexandria, a third century
Greek mathematician) is a polynomial equation where the variables can only take on integer
values. Although you may not realize it, you have seen Diophantine equations before: one of
the most famous Diophantine equations is:
x的n次方 + y的n次方 = z的n次方
For n=2, there are infinitely many solutions (values for x, y and z) called the Pythagorean
triples. For larger values of n, Fermat’s famous “last theorem” states that
there do not exist any positive integer solutions for x, y and z that satisfy this equation. For
centuries, mathematicians have studied different Diophantine equations; besides Fermat’s last
theorem, some famous ones include Pell’s equation, and the Erdos-Strauss conjecture. For more
information on this intriguing branch of mathematics, you may find the Wikipedia article of
interest.
there do not exist any positive integer solutions for x, y and z that satisfy this equation. For
centuries, mathematicians have studied different Diophantine equations; besides Fermat’s last
theorem, some famous ones include Pell’s equation, and the Erdos-Strauss conjecture. For more
information on this intriguing branch of mathematics, you may find the Wikipedia article of
interest.
We are not certain that McDonald’s knows about Diophantine equations (actually we doubt that
they do), but they use them! McDonald’s sells Chicken McNuggets in packages of 6, 9 or 20
McNuggets. Thus, it is possible, for example, to buy exactly 15 McNuggets (with one package of
6 and a second package of 9), but it is not possible to buy exactly 16 nuggets, since no nonnegative
integer combination of 6’s, 9’s and 20’s adds up to 16. To determine if it is possible to
buy exactly n McNuggets, one has to solve a Diophantine equation: find non-negative integer
values of a, b, and c, such that
6a + 9b + 20c = n.
buy exactly n McNuggets, one has to solve a Diophantine equation: find non-negative integer
values of a, b, and c, such that
6a + 9b + 20c = n.
Problem 1.
Show that it is possible to buy exactly 50, 51, 52, 53, 54, and 55 McNuggets, by finding
solutions to the Diophantine equation. You can solve this in your head, using paper and pencil,
or writing a program. However you chose to solve this problem, list the combinations of 6, 9
and 20 packs of McNuggets you need to buy in order to get each of the exact amounts.
Given that it is possible to buy sets of 50, 51, 52, 53, 54 or 55 McNuggets by combinations of 6,
9 and 20 packs, show that it is possible to buy 56, 57,…, 65 McNuggets. In other words, show
how, given solutions for 50-55, one can derive solutions for 56-65.
9 and 20 packs, show that it is possible to buy 56, 57,…, 65 McNuggets. In other words, show
how, given solutions for 50-55, one can derive solutions for 56-65.
Theorem: If it is possible to buy x, x+1,…, x+5 sets of McNuggets, for some x, then it is
possible to buy any number of McNuggets >= x, given that McNuggets come in 6, 9 and 20
packs.
possible to buy any number of McNuggets >= x, given that McNuggets come in 6, 9 and 20
packs.
问题1就是列出出售50, 51, 52, 53, 54, 55块麦乐鸡时,需要卖出多少组6个鸡块,多少组9个,
和多少组20个。并列出56, 57..., 65的情况,然后我们得出结论:如果可以买到x, x+1,..., x+5
那么对于任意大于x块鸡块,咱们都可以买到。
a=5, b=0, c=1: n=6*5+9*0+20*1=50
a=7, b=1, c=0: n=6*7+9*1+20*0=51
a=2, b=0, c=2: n=6*2+9*0+20*2=52
a=4, b=1, c=1: n=6*4+9*1+20*1=53
a=9, b=0, c=0: n=6*9+9*0+20*0=54
a=1, b=1, c=2: n=6*1+9*1+20*2=55
Problem 2.
Explain, in English, why this theorem is true.
Save your answers for problems 1 and 2 as ps2.txt.
Explain, in English, why this theorem is true.
Save your answers for problems 1 and 2 as ps2.txt.
证明上面的结论
Solving a Diophantine Equation
Using this theorem, we can write an exhaustive search to find the largest number of McNuggets
that cannot be bought in exact quantity. The format of the search should probably follow this
outline:
Hypothesize possible instances of numbers of McNuggets that cannot be purchased
exactly, starting with 1
For each possible instance, called n,
Test if there exists non-negative integers a, b, and c, such that
6a+9b+20c = n. (This can be done by looking at all feasible
combinations of a, b, and c)
If not, n cannot be bought in exact quantity, save n
When you have found six consecutive values of n that in fact pass the test of
having an exact solution, the last answer that was saved (not the last value
of n that had a solution) is the correct answer, since you know by the
theorem that any amount larger can also be bought in exact quantity
that cannot be bought in exact quantity. The format of the search should probably follow this
outline:
Hypothesize possible instances of numbers of McNuggets that cannot be purchased
exactly, starting with 1
For each possible instance, called n,
Test if there exists non-negative integers a, b, and c, such that
6a+9b+20c = n. (This can be done by looking at all feasible
combinations of a, b, and c)
If not, n cannot be bought in exact quantity, save n
When you have found six consecutive values of n that in fact pass the test of
having an exact solution, the last answer that was saved (not the last value
of n that had a solution) is the correct answer, since you know by the
theorem that any amount larger can also be bought in exact quantity
Problem 3.
Write an iterative program that finds the largest number of McNuggets that cannot be bought in
exact quantity. Your program should print the answer in the following format (where the correct
number is provided in place of <n>):
“Largest number of McNuggets that cannot be bought in exact quantity: <n>”
Hint: your program should follow the outline above.
Hint: think about what information you need to keep track of as you loop through possible ways
of buying exactly n McNuggets. This will guide you in deciding what state variables you will need
to utilize.
Save your code for Problem 3 in ps2a.py.
Write an iterative program that finds the largest number of McNuggets that cannot be bought in
exact quantity. Your program should print the answer in the following format (where the correct
number is provided in place of <n>):
“Largest number of McNuggets that cannot be bought in exact quantity: <n>”
Hint: your program should follow the outline above.
Hint: think about what information you need to keep track of as you loop through possible ways
of buying exactly n McNuggets. This will guide you in deciding what state variables you will need
to utilize.
Save your code for Problem 3 in ps2a.py.
We can generalize this idea to work with any size packages of McNuggets, not just 6, 9, and 20.
For simplicity, however, we will assume that McDonald’s still provides McNuggets in three
different sized packages.
For simplicity, however, we will assume that McDonald’s still provides McNuggets in three
different sized packages.
Program ps2a.py
nugget = 1 # possible number of McNuggets
count = 0 # consecutive values of n pass the test
maxNugget = nugget
while count < 6:
hasSolution = False
for a in range(0, int(nugget / 6) + 1):
for b in range(0, int(nugget / 9) + 1):
for c in range(0, int(nugget / 20) + 1):
if nugget == 6 * a + 9 * b + 20 * c:
hasSolution = True
break
if not hasSolution:
maxNugget = nugget
count = 0
else:
count += 1
nugget += 1
print 'Largest number of McNuggets that cannot be bought in exact quantity: %d'% maxNugget
count = 0 # consecutive values of n pass the test
maxNugget = nugget
while count < 6:
hasSolution = False
for a in range(0, int(nugget / 6) + 1):
for b in range(0, int(nugget / 9) + 1):
for c in range(0, int(nugget / 20) + 1):
if nugget == 6 * a + 9 * b + 20 * c:
hasSolution = True
break
if not hasSolution:
maxNugget = nugget
count = 0
else:
count += 1
nugget += 1
print 'Largest number of McNuggets that cannot be bought in exact quantity: %d'% maxNugget
有了上面的结论,我们只需找到连续可买的五个数x,x+1,...,x+5,在x前买不到的最大数就是
最大的买不到的麦乐鸡块数。
注意:range(0,2)产生结果是[0, 1]
Problem 4.
Assume that the variable packages is bound to a tuple of length 3, the values of which specify
the sizes of the packages, ordered from smallest to largest. Write a program that uses
exhaustive search to find the largest number (less than 200) of McNuggets that cannot be
bought in exact quantity. We limit the number to be less than 200 (although this is an arbitrary
choice) because in some cases there is no largest value that cannot be bought in exact quantity,
and we don’t want to search forever. Please use ps2b_template.py to structure your code.
Have your code print out its result in the following format:
Assume that the variable packages is bound to a tuple of length 3, the values of which specify
the sizes of the packages, ordered from smallest to largest. Write a program that uses
exhaustive search to find the largest number (less than 200) of McNuggets that cannot be
bought in exact quantity. We limit the number to be less than 200 (although this is an arbitrary
choice) because in some cases there is no largest value that cannot be bought in exact quantity,
and we don’t want to search forever. Please use ps2b_template.py to structure your code.
Have your code print out its result in the following format:
“Given package sizes <x>, <y>, and <z>, the largest number of McNuggets that
cannot be bought in exact quantity is: <n>”
cannot be bought in exact quantity is: <n>”
Test your program on a variety of choices, by changing the value for packages. Include the
case (6,9,20), as well as some other test cases of your own choosing.
Save your code for Problem 4 in ps2b.py.
case (6,9,20), as well as some other test cases of your own choosing.
Save your code for Problem 4 in ps2b.py.
Program ps2b.py
###
### template of code for Problem 4 of Problem Set 2, Fall 2008
###
bestSoFar = 0 # variable that keeps track of largest number
# of McNuggets that cannot be bought in exact quantity
packages = (6,9,10) # variable that contains package sizes
count = 0 # consecutive values of n pass the test
for n in range(1, 150): # only search for solutions up to size 150
## complete code here to find largest size that cannot be bought
## when done, your answer should be bound to bestSoFar
if count > 6:
break
hasSolution = False
for a in range(0, int(n / packages[0]) + 1):
for b in range(0, int(n / packages[1]) + 1):
for c in range(0, int(n / packages[2]) + 1):
if n == packages[0] * a + packages[1] * b + packages[2] * c:
hasSolution = True
break
if not hasSolution:
bestSoFar = n
count = 0
else:
count += 1
n += 1
print 'Given package sizes <%d>,<%d>,<%d>, the largest number of McNuggets that cannot be bought in exact quantity: %d'% (packages[0], packages[1], packages[2], bestSoFar)
### template of code for Problem 4 of Problem Set 2, Fall 2008
###
bestSoFar = 0 # variable that keeps track of largest number
# of McNuggets that cannot be bought in exact quantity
packages = (6,9,10) # variable that contains package sizes
count = 0 # consecutive values of n pass the test
for n in range(1, 150): # only search for solutions up to size 150
## complete code here to find largest size that cannot be bought
## when done, your answer should be bound to bestSoFar
if count > 6:
break
hasSolution = False
for a in range(0, int(n / packages[0]) + 1):
for b in range(0, int(n / packages[1]) + 1):
for c in range(0, int(n / packages[2]) + 1):
if n == packages[0] * a + packages[1] * b + packages[2] * c:
hasSolution = True
break
if not hasSolution:
bestSoFar = n
count = 0
else:
count += 1
n += 1
print 'Given package sizes <%d>,<%d>,<%d>, the largest number of McNuggets that cannot be bought in exact quantity: %d'% (packages[0], packages[1], packages[2], bestSoFar)