排列
排列 (permutation) 指的是:有限多個元素以任何順序所做的一種安排,需動用到全部的元素,叫做這些給定元素的一種排列。
例如:有 3 個字母 a, b, c,按照不同的排列順序,可以有幾種排列方式?共有以下情形:abc, acb, bac, bca, cab, cba 這 6 種排列。
我們可以這樣想,在第一個位置有 3 種選擇,第二個位置剩下 2 種選擇,第三個位置只有 1 種選擇。所以共有 3 × 2 × 1 = 6 種排列方式。也就是 3 階乘 (factorial of 3),數學以 3! 來表示。
同理,若有 9 個不同字母,就有 9! 種排列方式。
在 Python 裡,math
函式庫裡,計算階乘的函數是 math.factorial(x)
,其中 x 需為正整數。
In [1]: import math In [2]: math.factorial(3) Out[2]: 6 In [3]: math.factorial(9) Out[3]: 362880
從 n 個相異元素中,所抽出的任一組 k 個元素集,若將具有相同的元素但順序不同的排列也視為相異時,共有幾種排列方式,稱之為有幾種排列數。
例如從 5 個字母 a, b, c, d, e 中,任取 2 個字母,順序不同也視為不同排列,有幾種排列數?會有:
ab, ac, ad, ae,
ba, bc, bd, be,
ca, cb, cd, ce,
da, db, dc, de,
ea, eb, ec, ed
會有以上 20 種排列數。
我們可以這麼想,任取 2 個字母,取第一個字母時有 5 種選擇,取第二個字母時只有 4 種選擇,所以共有 20 種排列數。
排列數
我們可以用 math.perm(n, k)
這個函數來計算排列數:
In [2]: math.perm(5, 2) Out[2]: 20
組合
組合 (combination):從 n 個相異元素中,所抽出的任一組 k 個元素集,稱為一個組合。在組合中,並不考慮元素出現的順序,不同順序也視為同一個組合。
例如從 5 個字母 a, b, c, d, e 中,任取 2 個字母,不考慮順序,有幾種組合?會有:
ab, ac, ad, ae, bc, bd, be, cd, ce, de 這 10 種組合。
組合數:從 n 個相異元去中取出 k 個元素的組合數,因為不同順序也視為同一種組合,所以組合數會是排列數除以 k! 。
組合數
Python 裡用 math.comb(n, k)
來計算組合數。
In [3]: math.comb(5, 2) Out[3]: 10
itertools 函式庫
這裡我們利用 itertools
這個函式庫,來呈現排列組合。首先匯入這個函式庫:
In [1]: import itertools
如果我們要把 “abcde" 這個字串做排列,可以用 permutations(n)
這個函數來產生所有排列的 list,我們把這個 list 命名為 perm1:
In [12]: perm1 = itertools.permutations("abcde")
再利用一個簡單的 for 迴圈,把 5! = 120種排列列印出來:
In [13]: for i in list(perm1): ...: print(i) ...: ('a', 'b', 'c', 'd', 'e') ('a', 'b', 'c', 'e', 'd') ('a', 'b', 'd', 'c', 'e') ('a', 'b', 'd', 'e', 'c') ('a', 'b', 'e', 'c', 'd') ('a', 'b', 'e', 'd', 'c') ('a', 'c', 'b', 'd', 'e') ('a', 'c', 'b', 'e', 'd') ('a', 'c', 'd', 'b', 'e') ('a', 'c', 'd', 'e', 'b') ('a', 'c', 'e', 'b', 'd') ('a', 'c', 'e', 'd', 'b') ('a', 'd', 'b', 'c', 'e') ('a', 'd', 'b', 'e', 'c') ('a', 'd', 'c', 'b', 'e') ('a', 'd', 'c', 'e', 'b') ('a', 'd', 'e', 'b', 'c') ('a', 'd', 'e', 'c', 'b') ('a', 'e', 'b', 'c', 'd') ('a', 'e', 'b', 'd', 'c') ('a', 'e', 'c', 'b', 'd') ('a', 'e', 'c', 'd', 'b') ('a', 'e', 'd', 'b', 'c') ('a', 'e', 'd', 'c', 'b') ('b', 'a', 'c', 'd', 'e') ('b', 'a', 'c', 'e', 'd') ('b', 'a', 'd', 'c', 'e') ('b', 'a', 'd', 'e', 'c') ('b', 'a', 'e', 'c', 'd') ('b', 'a', 'e', 'd', 'c') ('b', 'c', 'a', 'd', 'e') ('b', 'c', 'a', 'e', 'd') ('b', 'c', 'd', 'a', 'e') ('b', 'c', 'd', 'e', 'a') ('b', 'c', 'e', 'a', 'd') ('b', 'c', 'e', 'd', 'a') ('b', 'd', 'a', 'c', 'e') ('b', 'd', 'a', 'e', 'c') ('b', 'd', 'c', 'a', 'e') ('b', 'd', 'c', 'e', 'a') ('b', 'd', 'e', 'a', 'c') ('b', 'd', 'e', 'c', 'a') ('b', 'e', 'a', 'c', 'd') ('b', 'e', 'a', 'd', 'c') ('b', 'e', 'c', 'a', 'd') ('b', 'e', 'c', 'd', 'a') ('b', 'e', 'd', 'a', 'c') ('b', 'e', 'd', 'c', 'a') ('c', 'a', 'b', 'd', 'e') ('c', 'a', 'b', 'e', 'd') ('c', 'a', 'd', 'b', 'e') ('c', 'a', 'd', 'e', 'b') ('c', 'a', 'e', 'b', 'd') ('c', 'a', 'e', 'd', 'b') ('c', 'b', 'a', 'd', 'e') ('c', 'b', 'a', 'e', 'd') ('c', 'b', 'd', 'a', 'e') ('c', 'b', 'd', 'e', 'a') ('c', 'b', 'e', 'a', 'd') ('c', 'b', 'e', 'd', 'a') ('c', 'd', 'a', 'b', 'e') ('c', 'd', 'a', 'e', 'b') ('c', 'd', 'b', 'a', 'e') ('c', 'd', 'b', 'e', 'a') ('c', 'd', 'e', 'a', 'b') ('c', 'd', 'e', 'b', 'a') ('c', 'e', 'a', 'b', 'd') ('c', 'e', 'a', 'd', 'b') ('c', 'e', 'b', 'a', 'd') ('c', 'e', 'b', 'd', 'a') ('c', 'e', 'd', 'a', 'b') ('c', 'e', 'd', 'b', 'a') ('d', 'a', 'b', 'c', 'e') ('d', 'a', 'b', 'e', 'c') ('d', 'a', 'c', 'b', 'e') ('d', 'a', 'c', 'e', 'b') ('d', 'a', 'e', 'b', 'c') ('d', 'a', 'e', 'c', 'b') ('d', 'b', 'a', 'c', 'e') ('d', 'b', 'a', 'e', 'c') ('d', 'b', 'c', 'a', 'e') ('d', 'b', 'c', 'e', 'a') ('d', 'b', 'e', 'a', 'c') ('d', 'b', 'e', 'c', 'a') ('d', 'c', 'a', 'b', 'e') ('d', 'c', 'a', 'e', 'b') ('d', 'c', 'b', 'a', 'e') ('d', 'c', 'b', 'e', 'a') ('d', 'c', 'e', 'a', 'b') ('d', 'c', 'e', 'b', 'a') ('d', 'e', 'a', 'b', 'c') ('d', 'e', 'a', 'c', 'b') ('d', 'e', 'b', 'a', 'c') ('d', 'e', 'b', 'c', 'a') ('d', 'e', 'c', 'a', 'b') ('d', 'e', 'c', 'b', 'a') ('e', 'a', 'b', 'c', 'd') ('e', 'a', 'b', 'd', 'c') ('e', 'a', 'c', 'b', 'd') ('e', 'a', 'c', 'd', 'b') ('e', 'a', 'd', 'b', 'c') ('e', 'a', 'd', 'c', 'b') ('e', 'b', 'a', 'c', 'd') ('e', 'b', 'a', 'd', 'c') ('e', 'b', 'c', 'a', 'd') ('e', 'b', 'c', 'd', 'a') ('e', 'b', 'd', 'a', 'c') ('e', 'b', 'd', 'c', 'a') ('e', 'c', 'a', 'b', 'd') ('e', 'c', 'a', 'd', 'b') ('e', 'c', 'b', 'a', 'd') ('e', 'c', 'b', 'd', 'a') ('e', 'c', 'd', 'a', 'b') ('e', 'c', 'd', 'b', 'a') ('e', 'd', 'a', 'b', 'c') ('e', 'd', 'a', 'c', 'b') ('e', 'd', 'b', 'a', 'c') ('e', 'd', 'b', 'c', 'a') ('e', 'd', 'c', 'a', 'b') ('e', 'd', 'c', 'b', 'a')
若我們要在 5 個字母中,任取 2 個字母,順序不同視為不同排列,共有 5! / 3! = 20 種排列數。可以用 permutations(n, k)
產生各種排列,再印出:
In [14]: perm2 = itertools.permutations("abcde", 2) In [15]: for i in list(perm2): ...: print(i) ...: ('a', 'b') ('a', 'c') ('a', 'd') ('a', 'e') ('b', 'a') ('b', 'c') ('b', 'd') ('b', 'e') ('c', 'a') ('c', 'b') ('c', 'd') ('c', 'e') ('d', 'a') ('d', 'b') ('d', 'c') ('d', 'e') ('e', 'a') ('e', 'b') ('e', 'c') ('e', 'd')
接著,考慮組合數的問題,若我們要在 5 個字母中,任取 2 個字母,忽略順序,共有幾種組合數?答案是:
= 10 種組合。
此時可以用 combinations(n, k)
這個函數:
In [2]: comb1 = itertools.combinations("abcde", 2) In [3]: for i in list(comb1): ...: print(i) ...: ('a', 'b') ('a', 'c') ('a', 'd') ('a', 'e') ('b', 'c') ('b', 'd') ('b', 'e') ('c', 'd') ('c', 'e') ('d', 'e')
參考閱讀:
https://docs.python.org/3.8/library/math.html
https://docs.python.org/3.8/library/itertools.html
https://docs.python.org/3.8/tutorial/controlflow.html#for-statements