■概要
「1、2、2、3、3」や「A、A、B、C、D、D」など、区別がつかない同じものを含む順列について、机上計算およびPythonを使用した計算処理の2種類の解答方法を示す。
■同じものを含む順列
5つの数字「1、2、2、3、3」を順番に並び替えた場合の数を考える。
下図は、見分けやすいように色分けしているが、同じ「1、2、2、3、3」であり、これらの重複分を合わせて1通りとする。

▼同じものを含む順列の公式
n個の値を全て使用するとき、同じものがそれぞれ「p個、q個、r個、・・・」あるとき、場合の数は、以下の公式で求めることができる。

「1、2、2、3、3」の個数は、それぞれ、「1:1個」、「2:2個」、「3:2個」であるため、順番に並び替えた場合の数は、以下の通りである。

なお、個数が1個の場合は、「1!」を計算しても「1」であるため、省略することができる。
■例題
▼問1
6つの数字「1、3、3、5、7、7」を全て使用して6桁の数字を作る時の場合の数を求める。
▼問2
8つの文字「anotools」を全て使用して文字列を作成する時の場合の数を求める。
■机上計算
▼問1
6つの数字「1、3、3、5、7、7」の個数は、それぞれ、「1:1個」、「3:2個」、「5:1個」、「7:2個」であるため、順番に並び替えた場合の数は、以下の通りである。

▼問2
8つの文字「anotools」の個数は、それぞれ、「a:1個」、「n:1個」、「o:3個」、「t:1個」、「l:1個」、「s:1個」であるため、順番に並び替えた場合の数は、以下の通りである。

■Pythonによる実装
▼フローチャート
同じものを含む順列を計算する関数について、フローチャートを下図に示す。

▼プログラム仕様
<処理名:同じものを含む順列を計算する関数>
・引数と戻り値
| 項目 | 型 | 内容 | 
|---|---|---|
| 第1引数 | リスト型 | 対象のデータ全量 | 
| 戻り値 | int型 | 同じものを含む順列の計算結果 | 
・処理概要
| 入力 | 処理内容 | 出力 | 
|---|---|---|
| – | 第1引数のリスト型データをタプル型に変換する。 ★タプル型に変換することで、重複分が削除される。 (イメージ) リスト型:[1, 2, 2, 3, 3] タプル型:(1, 2, 3) | – | 
| – | 同じ個数の計算結果初期値をセットする。 初期値:1 ※「p!×q!×r!・・・」の計算結果格納変数 | – | 
| – | ■ループ処理:タプル型の要素数分繰り返し |▼条件分岐:リスト型のデータ |【同じものがある場合(>1)】 ||同じ個数の計算結果に階乗結果を追加する。(p! * q! * r!…) |▲ ■ | – | 
| – | リスト型の全量をセットする。 | – | 
| – | 場合の数を算出する。 n! / (p! * q! * r!…) | – | 
▼サンプルコード
import math
# 同じを含む順列を計算する関数
def same_permutation(list_data:list) -> int:
    # タプル型に変換し、同じものを削除
    taple_data = set(list_data)
    # 同じ個数の計算結果初期値
    same_count_result = 1
    # タプル型の要素数分繰り返し
    for i in taple_data:
        # 同じものがある場合
        if list_data.count(i) > 1:
            # 同じ個数の計算結果に階乗結果を追加(p! * q! * r!...)
            same_count_result = same_count_result * math.factorial(list_data.count(i))
    # リストの全量をセット
    count_all_data = len(list_data)
    # 場合の数を算出(n! / (p! * q! * r!...))
    ans = math.factorial(count_all_data) / same_count_result
    return int(ans)
if __name__ == '__main__':
    q1 = [1,3,3,5,7,7]
    print('問1:', same_permutation(q1), '通り')
    q2 = ['a', 'n', 'o', 't', 'o', 'o', 'l', 's']
    print('問2:', same_permutation(q2), '通り')
▼実行結果
問1: 180 通り
問2: 6720 通り


コメント