机器学习必须懂的排列与组合

排列的基本概念

实验与事件

在机器学习中,我们会使用同样的条件重复进行实验,然后观察与储存执行结果。

事件结果

有多少条回家路

乘法原则:假设有2个事件,其中事件A与B会先后发生。

加法原则:假设有2个事件,其中事件A与事件B只会发生一件。

排列组合

在数学的应用中可以使用下列公式:

nPr

P是愿意是Permutation(排列),指从n个数字中取r个数字 列出排列结果。

列出_{4}\textrm{P}_{3}的元素组合数量,以及所有结果。

import itertools
n = {1, 2, 3, 4}
r = 3
A = set(itertools.permutations(n, 3))
print('元素数量 = {}'.format(len(A)))
for a in A:
    print(a)

运行结果:

[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\tempCodeRunnerFile.py"
元素数量 = 24
(2, 1, 3)
(4, 2, 1)
(3, 2, 1)
(3, 2, 4)
(3, 1, 2)
(1, 4, 2)
(3, 4, 1)
(4, 1, 2)
(4, 3, 2)
(4, 2, 3)
(1, 2, 4)
(3, 1, 4)
(1, 3, 2)
(4, 3, 1)
(2, 4, 1)
(2, 1, 4)
(1, 2, 3)
(1, 3, 4)
(3, 4, 2)
(1, 4, 3)
(2, 3, 4)
(4, 1, 3)
(2, 4, 3)
(2, 3, 1)

[Done] exited with code=0 in 0.216 seconds

假设基因是配对存在,现在有a、b、c、d、e五种基因,每2个不同基因可以配对,请问有几个组合?列出排列可能结果。

import itertools
n = {'a', 'b', 'c', 'd', 'e'}
r = 2
A = set(itertools.permutations(n, 2))
print('基因配对组合数量 = {}'.format(len(A)))
for a in A:
    print(a)

运行结果:

[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\tempCodeRunnerFile.py"
基因配对组合数量 = 20
('c', 'd')
('d', 'e')
('a', 'b')
('d', 'b')
('b', 'd')
('e', 'b')
('d', 'a')
('a', 'c')
('c', 'e')
('e', 'a')
('b', 'e')
('d', 'c')
('c', 'b')
('e', 'c')
('a', 'd')
('c', 'a')
('b', 'a')
('e', 'd')
('b', 'c')
('a', 'e')

[Done] exited with code=0 in 0.334 seconds

阶乘的概念

 nPr

计算n个数字中取r个进行排列组合有多少种结果,可以得到下列公式:

n*(n-1)*...(n-r+1)

由于n=r,所以上述公式可以改写如下:

n*(n-1)*...1

将自然数从1到n每次加1的连乘,就是阶乘。表达:n!

使用itertools模块搭配permutations()方法,计算业务员拜访路径数,同时列出所有路径。

import itertools
n = {'A', 'B', 'C', 'D', 'E'}
r = 5
A = set(itertools.permutations(n, 5))
print('业务员路径数 = {}'.format(len(A)))
for a in A:
    print(a)

运行结果如下:

[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\ch12_3.py"
业务员路径数 = 120
('C', 'D', 'A', 'E', 'B')
('C', 'D', 'A', 'B', 'E')
('B', 'E', 'D', 'C', 'A')
('B', 'D', 'E', 'A', 'C')
('B', 'D', 'A', 'C', 'E')
('A', 'C', 'B', 'E', 'D')
('D', 'A', 'C', 'B', 'E')
('D', 'C', 'A', 'E', 'B')
('A', 'E', 'D', 'C', 'B')
('B', 'A', 'C', 'D', 'E')
('E', 'A', 'D', 'B', 'C')
('A', 'D', 'C', 'B', 'E')
('D', 'A', 'B', 'C', 'E')
('D', 'E', 'C', 'B', 'A')
('E', 'B', 'D', 'C', 'A')
('A', 'B', 'D', 'C', 'E')
('D', 'C', 'E', 'A', 'B')
('E', 'A', 'C', 'B', 'D')
('B', 'C', 'A', 'E', 'D')
('A', 'E', 'B', 'C', 'D')
('A', 'C', 'B', 'D', 'E')
('A', 'E', 'C', 'B', 'D')
('D', 'E', 'A', 'C', 'B')
('E', 'B', 'C', 'A', 'D')
('E', 'D', 'A', 'B', 'C')
('D', 'C', 'B', 'A', 'E')
('E', 'D', 'C', 'A', 'B')
('E', 'C', 'D', 'B', 'A')
('C', 'B', 'E', 'D', 'A')
('A', 'B', 'D', 'E', 'C')
('D', 'B', 'A', 'C', 'E')
('C', 'E', 'B', 'D', 'A')
('D', 'A', 'E', 'B', 'C')
('E', 'A', 'C', 'D', 'B')
('A', 'B', 'C', 'D', 'E')
('C', 'D', 'E', 'B', 'A')
('B', 'A', 'E', 'D', 'C')
('B', 'C', 'E', 'A', 'D')
('D', 'C', 'A', 'B', 'E')
('D', 'C', 'B', 'E', 'A')
('C', 'E', 'D', 'A', 'B')
('E', 'D', 'C', 'B', 'A')
('A', 'D', 'E', 'C', 'B')
('D', 'B', 'A', 'E', 'C')
('B', 'D', 'E', 'C', 'A')
('C', 'A', 'D', 'E', 'B')
('E', 'B', 'C', 'D', 'A')
('C', 'B', 'D', 'A', 'E')
('B', 'C', 'D', 'A', 'E')
('E', 'C', 'B', 'D', 'A')
('B', 'D', 'C', 'A', 'E')
('D', 'B', 'E', 'C', 'A')
('A', 'B', 'E', 'C', 'D')
('D', 'B', 'E', 'A', 'C')
('A', 'D', 'B', 'C', 'E')
('A', 'C', 'D', 'B', 'E')
('A', 'E', 'D', 'B', 'C')
('D', 'E', 'B', 'C', 'A')
('D', 'E', 'B', 'A', 'C')
('E', 'B', 'A', 'C', 'D')
('B', 'E', 'C', 'A', 'D')
('E', 'A', 'B', 'C', 'D')
('D', 'A', 'B', 'E', 'C')
('B', 'C', 'A', 'D', 'E')
('D', 'C', 'E', 'B', 'A')
('A', 'C', 'E', 'B', 'D')
('A', 'D', 'B', 'E', 'C')
('C', 'B', 'D', 'E', 'A')
('D', 'E', 'A', 'B', 'C')
('B', 'C', 'D', 'E', 'A')
('B', 'D', 'C', 'E', 'A')
('C', 'A', 'E', 'B', 'D')
('E', 'C', 'D', 'A', 'B')
('C', 'D', 'E', 'A', 'B')
('B', 'A', 'E', 'C', 'D')
('A', 'C', 'E', 'D', 'B')
('E', 'D', 'B', 'A', 'C')
('E', 'A', 'B', 'D', 'C')
('A', 'E', 'B', 'D', 'C')
('C', 'B', 'A', 'E', 'D')
('E', 'D', 'B', 'C', 'A')
('E', 'C', 'A', 'D', 'B')
('B', 'A', 'D', 'C', 'E')
('C', 'D', 'B', 'A', 'E')
('C', 'E', 'A', 'D', 'B')
('A', 'D', 'E', 'B', 'C')
('E', 'A', 'D', 'C', 'B')
('C', 'B', 'E', 'A', 'D')
('B', 'E', 'D', 'A', 'C')
('D', 'E', 'C', 'A', 'B')
('B', 'A', 'C', 'E', 'D')
('C', 'E', 'B', 'A', 'D')
('C', 'B', 'A', 'D', 'E')
('B', 'A', 'D', 'E', 'C')
('D', 'A', 'C', 'E', 'B')
('C', 'A', 'B', 'E', 'D')
('B', 'C', 'E', 'D', 'A')
('E', 'D', 'A', 'C', 'B')
('E', 'C', 'A', 'B', 'D')
('D', 'B', 'C', 'A', 'E')
('A', 'D', 'C', 'E', 'B')
('B', 'E', 'A', 'D', 'C')
('C', 'D', 'B', 'E', 'A')
('C', 'E', 'A', 'B', 'D')
('B', 'D', 'A', 'E', 'C')
('E', 'B', 'D', 'A', 'C')
('D', 'A', 'E', 'C', 'B')
('B', 'E', 'A', 'C', 'D')
('C', 'A', 'E', 'D', 'B')
('A', 'B', 'E', 'D', 'C')
('C', 'A', 'B', 'D', 'E')
('C', 'A', 'D', 'B', 'E')
('D', 'B', 'C', 'E', 'A')
('E', 'C', 'B', 'A', 'D')
('A', 'C', 'D', 'E', 'B')
('A', 'E', 'C', 'D', 'B')
('E', 'B', 'A', 'D', 'C')
('B', 'E', 'C', 'D', 'A')
('C', 'E', 'D', 'B', 'A')
('A', 'B', 'C', 'E', 'D')

[Done] exited with code=0 in 0.361 seconds

可以使用math模块的factorial(),执行阶乘运算。

>>> import math
>>> math.factorial(5)
120
>>>

假设有30个城市要拜访,请问有多少种拜访路径?

>>> math.factorial(30)
265252859812191058636308480000000
>>>

计算拜访30个城市的路径,假设超级计算机每秒可以处理10兆个路径,计算需要多少年可以得到所有路径。

import math

N = 30
times = 10000000000000              # 计算机每秒可处理数列数目
day_secs = 60 * 60 * 24             # 一天秒数
year_secs = 365 * day_secs          # 一年秒数
combinations = math.factorial(N)    # 组合方式
years = combinations / (times * year_secs)
print("需要 %d 年才可以获得结果" % years)

运行结果如下

[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\tempCodeRunnerFile.py"
需要 841111300774 年才可以获得结果

[Done] exited with code=0 in 0.31 seconds

重复排列

n\sqcap r=n^{r}

n是数字数量,r是数列个数。

将1、2、3、4、5排出三位数,数字可以重复使用,列出可以有多少种排法,同时输出结果。

import itertools
n = {1, 2, 3, 4, 5}
A = set(itertools.product(n, n, n))
print('排列组合 = {}'.format(len(A)))
for a in A:
    print(a)

运行结果:

[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\ch12_5.py"
排列组合 = 125
(5, 3, 3)
(5, 4, 2)
(2, 2, 5)
(3, 2, 1)
(5, 2, 4)
(5, 5, 3)
(3, 1, 5)
(3, 3, 2)
(4, 1, 2)
(2, 4, 5)
(5, 3, 5)
(5, 4, 4)
(3, 5, 2)
(4, 4, 3)
(1, 3, 2)
(5, 5, 5)
(3, 3, 4)
(4, 1, 4)
(4, 3, 1)
(1, 1, 2)
(5, 1, 1)
(1, 5, 2)
(3, 5, 4)
(4, 2, 2)
(4, 4, 5)
(1, 3, 4)
(1, 4, 3)
(3, 4, 5)
(1, 1, 4)
(5, 1, 3)
(1, 5, 4)
(2, 2, 2)
(4, 2, 4)
(2, 5, 4)
(5, 2, 1)
(3, 1, 2)
(1, 4, 5)
(2, 4, 2)
(5, 1, 5)
(5, 3, 2)
(5, 4, 1)
(2, 2, 4)
(5, 2, 3)
(1, 2, 1)
(3, 1, 4)
(3, 3, 1)
(3, 2, 3)
(5, 4, 3)
(3, 5, 1)
(2, 1, 1)
(4, 4, 2)
(4, 5, 1)
(5, 2, 5)
(1, 3, 1)
(1, 2, 3)
(3, 3, 3)
(3, 2, 5)
(3, 4, 2)
(2, 3, 1)
(4, 3, 3)
(5, 4, 5)
(1, 5, 1)
(3, 5, 3)
(2, 1, 3)
(2, 5, 1)
(4, 4, 4)
(4, 5, 3)
(1, 3, 3)
(1, 2, 5)
(1, 4, 2)
(3, 3, 5)
(3, 4, 4)
(2, 3, 3)
(4, 3, 5)
(2, 1, 5)
(2, 5, 3)
(3, 1, 1)
(4, 5, 5)
(1, 4, 4)
(5, 5, 2)
(4, 1, 1)
(2, 3, 5)
(2, 4, 4)
(5, 3, 4)
(2, 5, 5)
(5, 2, 2)
(3, 1, 3)
(3, 2, 2)
(5, 5, 4)
(4, 1, 3)
(1, 1, 1)
(4, 4, 1)
(4, 2, 1)
(1, 2, 2)
(3, 2, 4)
(3, 4, 1)
(4, 1, 5)
(4, 3, 2)
(1, 1, 3)
(5, 1, 2)
(1, 5, 3)
(2, 1, 2)
(2, 2, 1)
(3, 5, 5)
(4, 2, 3)
(4, 5, 2)
(1, 2, 4)
(1, 4, 1)
(3, 4, 3)
(1, 3, 5)
(2, 3, 2)
(2, 4, 1)
(4, 3, 4)
(1, 1, 5)
(5, 1, 4)
(5, 3, 1)
(1, 5, 5)
(2, 1, 4)
(2, 2, 3)
(2, 5, 2)
(4, 2, 5)
(4, 5, 4)
(5, 5, 1)
(2, 3, 4)
(2, 4, 3)

[Done] exited with code=0 in 0.291 seconds

组合

组合的英文是combination。不考虑排列方式。

组合的基本公式如下:nCr

下列方式表达:

C_{n}^{r}或者\binom{n}{r}

n是数列个数,r是所选取的数字个数。

至于有多少种组合,使用下列公式:

nCr=\frac{nPr}{r!}

使用程序验证组合。

import itertools
n = {1, 2, 3, 4, 5}
A = set(itertools.combinations(n, 3))
print('组合 = {}'.format(len(A)))
for a in A:
    print(a)

运行结果如下:

[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\tempCodeRunnerFile.py"
组合 = 10
(2, 4, 5)
(1, 3, 5)
(1, 2, 3)
(1, 3, 4)
(2, 3, 5)
(3, 4, 5)
(2, 3, 4)
(1, 2, 5)
(1, 4, 5)
(1, 2, 4)

[Done] exited with code=0 in 0.341 seconds

计算掷2颗骰子,当2颗骰子的数字不同时有多少种组合。

import itertools
n = {1, 2, 3, 4, 5, 6}
A = set(itertools.combinations(n, 2))
print('组合 = {}'.format(len(A)))
for a in A:
    print(a)

运行结果如下:

[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\tempCodeRunnerFile.py"
组合 = 15
(2, 4)
(1, 2)
(3, 4)
(1, 5)
(4, 6)
(1, 4)
(2, 3)
(4, 5)
(2, 6)
(5, 6)
(3, 6)
(1, 6)
(2, 5)
(1, 3)
(3, 5)

[Done] exited with code=0 in 0.485 seconds

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值