王德貴
“群牛問題”在古希臘科學(xué)家阿基米德的研究課題中比較特別,是以詩句的形式出現(xiàn)在給埃拉托塞尼的一封信中。雖然其真實(shí)性有待考證,因?yàn)椤叭号栴}”大概很早以前就已存在,阿基米德只是重新研究而已,但歷史上對(duì)這個(gè)問題的研究,卻豐富了初等數(shù)論的內(nèi)容。
下面我們也來分析一下群牛問題,并用Python求解驗(yàn)證。
太陽神有一牛群,由白、黑、花、棕四種顏色的公、母牛組成。
在公牛中,白牛數(shù)多于棕牛數(shù),多出之?dāng)?shù)相當(dāng)于黑牛數(shù)的1/2+1/3;黑牛數(shù)多于棕牛數(shù),多出之?dāng)?shù)相當(dāng)于花牛數(shù)的1/4+1/5;花牛數(shù)多于棕牛數(shù),多出之?dāng)?shù)相當(dāng)于白牛數(shù)的1/6+1/7。
在母牛中,白牛數(shù)是全體黑牛數(shù)的1/3+1/4;黑牛數(shù)是全體花牛數(shù)1/4+1/5;花牛數(shù)是全體棕牛數(shù)的1/5+1/6;棕牛數(shù)是全體白牛數(shù)的1/6+1/7。
問這牛群是怎樣組成的?
通過了解知名數(shù)學(xué)難題的解題思路,并將其用于Python編程,提高我們的數(shù)學(xué)和編程水平。在我搜索的“100個(gè)數(shù)學(xué)難題”中第一個(gè)問題就是“群牛問題”,經(jīng)過分析和研究,自覺頗有收獲。
這是一道解不定方程組問題,有8個(gè)未知數(shù),7個(gè)方程,有無數(shù)組解,我們可以求出最小正整數(shù)解。這個(gè)解數(shù)值較大,即使通過Python求最小正整數(shù)解也不容易。
按照編程解方程的慣性思路,方程的解可以使用枚舉法去求。結(jié)果當(dāng)Python程序運(yùn)行后卻沒有輸出結(jié)果(所有程序后面給出)。分析原因發(fā)現(xiàn)是因?yàn)榻獾臄?shù)值過大,必須尋求更好的求解方法。
最普通的思路,不需要過多考慮,用枚舉法一個(gè)個(gè)去測(cè)試(圖1)。
測(cè)試1萬個(gè)數(shù)的時(shí)間復(fù)雜度是10的12次方,需要運(yùn)行30多個(gè)小時(shí)。通過搜索已知最小正整數(shù)解的值很大,枚舉法獲得結(jié)果的時(shí)間過長,必須去尋找更簡(jiǎn)捷的方法。
(1)驗(yàn)證解出錯(cuò)
在網(wǎng)上搜索到了群牛問題的一組正整數(shù)解,代入方程直接驗(yàn)證,運(yùn)行結(jié)果后面4個(gè)全部為“False”(圖2)。
False表示解并不符合原題目的這項(xiàng)條件(圖3)。
(2)驗(yàn)證另一組帶n的解也出錯(cuò)
搜索到的另一組解是帶n的,代入方程驗(yàn)證結(jié)果更奇怪(圖4)。
當(dāng)n=1時(shí),有兩個(gè)“False”(圖5)。
當(dāng)n=5時(shí),有1個(gè)“False”(圖6)。
為什么我把搜到的答案拿來驗(yàn)證都沒法通過,問題出在哪里呢?為什么不同的解驗(yàn)算的“False”數(shù)目還不一樣?
在分析這些問題產(chǎn)生的原因過程中,我發(fā)現(xiàn)了一個(gè)庫函數(shù)Sympy,它可以幫我解決問題!
(1)SymPy庫簡(jiǎn)介
SymPy庫函數(shù)是一個(gè)符號(hào)計(jì)算的Python庫。它的目標(biāo)是成為一個(gè)全功能的計(jì)算機(jī)代數(shù)系統(tǒng),同時(shí)保持代碼簡(jiǎn)潔、易于理解和擴(kuò)展。它完全由Python寫成,不依賴于外部庫。SymPy支持符號(hào)計(jì)算、高精度計(jì)算、模式匹配、繪圖、解方程、微積分、組合數(shù)學(xué)、離散數(shù)學(xué)、幾何學(xué)、概率與統(tǒng)計(jì)、物理學(xué)等方面的功能。
SymPy的安裝和使用這里不做介紹,我只分析它求解方程的方法SymPy.solve()。Solve()是一個(gè)數(shù)學(xué)術(shù)語,主要是用來求解代數(shù)方程(多項(xiàng)式方程)的符號(hào)解析解。
(2)方程求解:先看個(gè)簡(jiǎn)單例子(圖7)。運(yùn)行就可以直接求出方程的解{x: -1, y: 4},感覺到Python的強(qiáng)大了嗎?
(3) 群牛問題求解方程