1.問題描述
比如9個數中取4個數的組合以及列出各種組合,該如何做?
我們可以考慮以下一個簡單組合:從1,2,3,4,5,6中,如何選取任意四個數的組合。
固定:1 2 3 ,組合有1234 1235 1236
固定1 2 4,組合有:1245 1246
固定1 2 5,組合有:1256
固定1 3 4,組合有:1345 1346
固定1 3 5,組合有:1356
固定1 4 5,組合有:1456
固定2 3 4,組合有:2345 2346
固定2 3 5,組合有:2356
固定2 4 5,組合有:2456
固定3 4 5,組合有:3456
共有15種組合
2.簡單實現一下組合算法
首先,我們分析上面列出的10個步驟,對於1),很明顯,在固定了1 2 3這三個數之后,第四個數就是4、5、6三個數進行了循環(還記得循環嗎,計算機最拿手的就是做循環)。其次,我們再分析1)2)3)這三個步驟中固定的數字,前兩個沒有變,都是1 2,只是第三個數在進行循環(又是循環)。
通過分析,我們可以找到這樣的規律:
1 先固定3個數,讓第四個數進行循環
2 讓第三個數循環,重復第一步
3 讓第二個數循環,重復第一步
4 讓第一個數循環,重復第一步
def combNumberLoop4(m, b): totalNumber = 0 for i in range(1, m+2-4): b[0] = i for j in range(i+1, m+2-3): b[1] = j for k in range(j+1, m+2-2): b[2] = k for l in range(k+1, m+2-1): b[3] = l print b totalNumber += 1 return totalNumber group=[99,99,99,99] print "\nUsing Loop: %d\n" % combNumberLoop4(6, group)
程序的輸出結果,正如之前分析的那樣。
3.如何遞歸解決組合問題
我們再回到C(6,4)問題,除了上面列出的十個步驟,我們換個思路:
如果在6個數中選定一個數,那么確定剩下的3個數是不是變為了“從5個數中選3個數的組合問題”了呢?以此類推,這似乎變成了一個“遞歸”問題了,確實,我們可以用遞歸的思路來解決這個問題。
對於C(m, n)列出所有組合的問題,可以按照一下的步驟來進行編程,這次我們按從后往前的順序來列出所有組合:
1 選定一個元素i,在范圍[m, n]內進行循環
2 將i 作為所求組合的最后一個元素
3 如果n-1>0,進行遞歸調用,求C(m-1, n-1);否則,輸出結果
4 重復①
注意,設計遞歸函數一定要有終止條件,否則會造成“死循環”。
實現的代碼如下:
def combNumber(m, n, b): global totalNumberR for i in range(m, n-1, -1): b[n-1] = i if n-1>0: combNumber(i-1,n-1,b) else: print b totalNumberR += 1 return totalNumberR group=[99,99,99,99,99] totalNumberR = 0 print "\nUsing Recursive: %d\n" % combNumber(7,5,group)
遞歸的使用,讓程序寫起來非常的簡潔,但是,在寫程序的時候,我有兩個地方(其實程序也就難在這兩個地方),折騰了好幾天才弄清楚:
首先是for循環的循環范圍如何確定;
其次是遞歸調用時使用的參數設計;
3.python提供的內置組合函數
def combinations_with_replacement(iterable, r): # combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC pool = tuple(iterable) n = len(pool) if not n and r: return indices = [0] * r yield tuple(pool[i] for i in indices) while True: for i in reversed(range(r)): if indices[i] != n - 1: break else: return indices[i:] = [indices[i] + 1] * (r - i) yield tuple(pool[i] for i in indices)
4.更多組合算法
請點擊我:https://docs.python.org/3/library/itertools.html?highlight=combinations#itertools.combinations