中國古代有個值得研究的問題:一隻公雞值五錢,一隻母雞值三錢,三隻小雞值一錢,現在要用百錢買百雞,請問公雞、母雞、小雞各多少只?這個問題就是著名的「百錢買百雞問題」,出自數學家張丘建的《算經》。
關於這問題我們應該怎樣進行邏輯思維分析,具體步驟如下:
1.列出所有條件:
(1) 雞的類型:公雞(cock)、母雞(hen)、小雞(chicken)
(2) 各種雞的數量:公雞數量=n1、母雞數量=n2、小雞數量=n3
(3) 各種雞的類型的價錢:公雞價錢=5、母雞價錢=3、小雞價錢=1/3
(4) 買雞組合的總價錢:100
(5) 雞的總數量:100
2.列關係式:
(1) 數量關係: n1+n2+n3=100
(2) 價錢關係: 5*cock+3*hen+chicken/3=100
3.確認要求解的數值:n1、n2、n3,為此百錢買百雞問題就轉化成解不定方程組。
使用程序進行開發設計,可以使用,以現在流行的Python程序為例,對「百錢買百雞」的課題進行學習討論。對於Python程序的安裝和環境搭建,這裡就不說明,大家可以搜索網絡資料進行學習。
程序代碼如下:
# _*_coding:utf8 _*_cock=[] #公雞列表hen=[] #母雞列表chicken=[] #小雞列表a=5 #公雞價錢b=3 #母雞價錢c=1/3 #小雞價錢n1=int(100/a) #公雞整數數值範圍n2=int(100/b) #母雞整數數值範圍n3=int(100/c) #小雞整數數值範圍for i in range(1,n1+1): #遍歷公雞列表for j in range(1,n2+1): #遍歷母雞列表 for k in range(1,n3+1): #遍歷小雞列表 if i+j+k==100 and i*a+j*b+k*c==100: #根據關係式要求選擇符合要求的數值cock.append(i) #將公雞數值添加到cock=[]列表中hen.append(j) #將母雞數值添加到hen=[]列表中chicken.append(k) #將小雞數值添加到chicken=[]列表中for m in range(int((len(cock)))): #列印所有結果print("結果",m+1,": ","公雞=",cock[m],",母雞=",hen[m],",小雞=",chicken[m])
程序運行結果:
結果 1 : 公雞= 4 ,母雞= 18 ,小雞= 78
結果 2 : 公雞= 8 ,母雞= 11 ,小雞= 81
結果 3 : 公雞= 12 ,母雞= 4 ,小雞= 84
程序分析:
程序使用利用窮舉循環的方法來求解,也就是通過對未知數可變範圍的窮舉,驗證方程在什麼情況下成立,從而得到相應的解。利用三層for循環嵌套:第一層循環控制公雞的數量,第二層控制母雞的數量,最內層控制小雞的數量。窮舉循環的特點就是把所有情況都考慮到,因此每層循環執行一次,對應循環變量的值就要加1。公雞、母雞、小雞數量的確定根據這三層循環我們可以得到很多種方案,在這些方案中有些是不符合n1+n2+n3=100並且5*cock+3*hen+chicken/3=100這兩個條件的,最後把合理的方案篩選出來。對於這種算法,它的整個邏輯思維十分清晰,優點沒有數據遺漏,缺點要耗費較多的運算時間。
為了進一步優化程序,我們重新對百錢買百雞問題進行再深入的分析,發現有一個隱藏的條件沒有使用,根據要求,買雞組合的總價錢為整數,公雞和母雞單價都為整數,只有小雞單價為小數,為此當買雞組合的總價錢100-公雞總價錢-母雞總價錢的結果必須是整數,又因為三隻小雞為1錢,所以小雞的數量必須是3的倍數,為此我們可以對小雞數量先進行關於3的倍數的篩選,以減少小雞的運算數據,減少運算工作。從而可以對程序進行優化:
代碼優化內容:
for i in range(1,n1+1): #遍歷公雞列表for j in range(1,n2+1): #遍歷母雞列表 if (100-i-j)%3==0: #選取小雞數量值中能整除3的數值(減少數值範圍)n3=100-i-j #對小雞數量進行賦值(3的倍數) if i*a+j*b+n3*c==100: #根據關係式要求選擇符合要求的數值cock.append(i) #將公雞數值添加到cock=[]列表中hen.append(j) #將母雞數值添加到hen=[]列表中chicken.append(n3) #將小雞數值添加到chicken=[]列表中
對於代碼優化後來說,公雞的數量i和母雞的數量j確定後,小雞的數量就固定為100-i-j,無須進行窮舉了,此時約束條件只有一個:5×i+3×j+n3=100;這樣我們利用兩重循環即可實現: 此算法只需嘗試20×33=660次,實現時約束條件中限定了小雞數量必須能被3整除時,只有小雞數量能被3整除時才會繼續進行約束條件「i*a+j*b+n3*c==100; 」的判斷。這樣省去了小雞不能整除3時需要進行的算術計算和條件判斷,將之前的20×33×300=198000次,減少至20×33=660次,大大提高了算法的效率。
相信各位對於關於百錢買百雞問題的邏輯思維有了更清晰的理解,根據此課題進行進一步拓展,可以使用不同的數量,可以嘗試計算千錢買千雞。感謝您讀完了子甲園的分享,歡迎留言一起聊聊天,共同探討各種邏輯思維和Python開發設計。