排列组合生成算法
这几天在研究组合数学,对一个经典的排列问题产生了兴趣,问题是这样的:
“有5个不同颜色的小球在一个盒子里面,取出一个小球,记下颜色再把该小球放入盒子,共取3次,请问总共有多少种排列情况?”
这个问题的答案应该是只要上过高中都能写出来的,它的答案其实就是5的3次方等于125。现在对于这个问题我想加深一点,列出所有的排列情况,也就是全部125种排列。这个加深后的问题也非常容易用Python代码实现。我实现了这个combinations_generater函数,可以打印出全部的排列情况。并且这个函数是个通用函数,也就是说它接受一个列表和抽取次数参数,能正确的打印出全部的排列。
## 排列组合生成算法
## Python3.4
def combinations_generater(elements, length):
"""对有N个元素的列表,取X次(可取重复的元素)。生成全部的组合情况。
参数: elements :有N个元素的列表。
length :取元素的次数,也就是生成的组合的长度。
结果: 一个组合生成器,使用for循环进行迭代,给出所有组合。
"""
result = [None for n in range(length)]
base = len(elements)
for num in range(base ** length):
for index in range(length):
result[index] = elements[num % base]
num = num // base
yield result
##test
print('From list(0,1,2,3,5) to choose 2 elements:')
for n in combinations_generater_no_repeat(['红','黄','蓝','黑','白'], 3):
print(n)
在写出了这个生成排列的函数后,我又考虑了另外一种情况:
“有5个不同颜色的小球在一个盒子里面,取出一个小球,记下颜色不把该小球放入盒子,共取3次,也就是不能重复抽取,请问总共有多少种组合情况?”
注意这个问题中,不重复抽取小球,并且不计小球的排列顺序了,所以这是一个组合问题。也有现成的数学组合公式来计算,但我还是写出了能生成所有组合的函数。
def combinations_generater_no_repeat(elements, length):
"""对有N个元素的列表,取X次(不可重复取元素)。生成全部的组合情况。
参数: elements :有N个元素的列表。
length :取元素的次数,也就是生成的组合的长度,不能大于元素列表的长度。
结果: 一个组合生成器,使用for循环进行迭代,给出所有组合。
"""
result_set = set()
base = len(elements)
for num in range(base ** length):
index_set = set()
for i in range(length):
index_set.add(num % base) #这一步是为了去除重复组合
num = num // base
result = tuple([elements[i] for i in index_set])
if (len(result) == length) & (result not in result_set):
result_set.add(result)
yield list(result)
## test
print('From list(0,1,2,3,5) to choose 2 elements, allowed to repeat:')
for n in combinations_generater(['红','黄','蓝','黑','白'], 3):
print(n)
2014-10-31
上一篇: 树的遍历算法实现 下一篇: 多进制整数运算系统