確率組み合わせ論の基本とされている「順列」は、Pythonで容易に計算することができます。
本記事では、そんなPython基礎となる順列の計算について、詳しくご説明します。
順列
順列(permutation)は、異なる\(n\)個の中から\(k\)個を選択し、一列に並べる際の、並べ方の総数のことです。
下式で表されます。
\(P\left( n,k\right) =\dfrac{n!}{\left( n-k\right) !}\)
以下に、Pythonを使用した順列の計算方法をご紹介します。
順列関数の実装
順列関数の実装例を以下にご紹介します。
#input
import math
def P(n, k = 1):
x = math.factorial(n)/math.factorial(n-k)
return int(x)
p = P(6,3)
print("P(6,3)={}".format(p))
#output
P(6,3)=120
上記関数は小さい数の計算には使用可能ですが、除数を大きくすると以下オーバーフローエラーが発生します。
#input
import math
def P(n, k = 1):
x = math.factorial(n)/math.factorial(n-k)
return int(x)
p = P(300,150)
print("P(300,150)={}".format(p))
#output
OverflowError: integer division result too large for a float
上記オーバーフローエラーが起こらないように定義した、組み込み型の実装例を以下にご紹介します。
#input
def P(n, k = 1):
p =1
if k < 0:
p = 0
elif n < 0:
p = 0
else:
for x in range(n, n-k, -1):
p = p * x
return p
print("P(300,150)={}".format(P(300,150)))
#output
P(300,150)=5356851815834042754281860328124213202444254808984038491714498316053238213073645568652210201325901577725508340538615147852234739179287406584949038405661424740015468799971756673145857679589546314759460557804712742167524648412637021549746023238721021994556466046952915488725705152021504748593244254904819157328965140480000000000000000000000000000000000000
scipy.special.perm()
SciPyのscipy.special.perm()を使用すると、第一引数に指定した\(n\)および第二引数に指定した\(k\)の順列を計算することができます。
第三引数はオプション(exact)ですが、Trueにすると正確な値を計算することが可能です。(デフォルト(False)はfloat型の近似値です。)
#input
from scipy import special as sp
p1 = sp.perm(10,5)
p2 = sp.perm(30,20)
p3 = sp.perm(30,20,exact=True)
print("P(10,5,False)={}".format(p1))
print("P(30,20,False)={}".format(p2))
print("P(30,20,True)={}".format(p3))
#output
P(10,5,False)=30240.0
P(30,20,False)=7.309657732919728e+25
P(30,20,True)=73096577329197271449600000
itertools.permutations()
itertoolsモジュールのitertools.permutations()を使用すると、イテレータとして順列を生成することができます。
第一引数にイテラブルオブジェクトを、第二引数に順列の選択個数\(k\)を指定します。
第二引数を省略した場合は、\(n=k\)として順列生成されます。
#input
from itertools import permutations as pmt
fluits = ["apple","orange","peach"]
P1 = pmt(fluits,2)
P2 = pmt(fluits)
print("apple,orange,peachから2個選ぶ順列:\n{}".format(list(P1)))
print("apple,orange,peachから3個選ぶ順列:\n{}".format(list(P2)))
#output
apple,orange,peachから2個選ぶ順列:
[('apple', 'orange'), ('apple', 'peach'), ('orange', 'apple'), ('orange', 'peach'), ('peach', 'apple'), ('peach', 'orange')]
apple,orange,peachから3個選ぶ順列:
[('apple', 'orange', 'peach'), ('apple', 'peach', 'orange'), ('orange', 'apple', 'peach'), ('orange', 'peach', 'apple'), ('peach', 'apple', 'orange'), ('peach', 'orange', 'apple')]
itertools.product()
itertoolsモジュールのitertools.product()を使用すると、イテレータとして重複順列を生成することができます。
第一引数にイテラブルオブジェクトを、第二引数(repeat)に重複を許可して選択する個数を指定します。
#input
from itertools import product as pro
#リストの要素を改行して出力する"pprint"のインポート
from pprint import pprint as pri
fish = ["tuna","salmon"]
P = pro(fish,repeat=3)
fish_list = list(P)
pri(fish_list)
#output
[('tuna', 'tuna', 'tuna'),
('tuna', 'tuna', 'salmon'),
('tuna', 'salmon', 'tuna'),
('tuna', 'salmon', 'salmon'),
('salmon', 'tuna', 'tuna'),
('salmon', 'tuna', 'salmon'),
('salmon', 'salmon', 'tuna'),
('salmon', 'salmon', 'salmon')]
まとめ
この記事では、Python基礎となる順列の計算方法について、ご説明しました。
本記事を参考に、ぜひ色々と試してみてください。
参考
Python学習用おすすめ教材
Pythonの基本を学びたい方向け
統計学基礎を学びたい方向け
Pythonの統計解析を学びたい方向け
おすすめプログラミングスクール
Pythonをはじめ、プログラミングを学ぶなら、TechAcademy(テックアカデミー)がおすすめです。
私も入っていますが、好きな時間に気軽にオンラインで学べますので、何より楽しいです。
現役エンジニアからマンツーマンで学べるので、一人では中々続かない人にも、向いていると思います。
無料体験ができますので、まずは試してみてください!