私は解決策を思いついたと思いますが、これが間違っている場合は修正してください。また、よりエレガントなソリューションがあるかどうかも知りたいです。
まず、組み合わせの総数を考え出しました。置換なしのすべての組み合わせは、n!/r!(nr)! に等しくなります。置換すると、(m+s-1)!/s!(m-1)! に等しくなります。ここで、m と n は選択するアイテムの数、r と s は実際に選択するアイテムの数です。各組み合わせで必要なアイテムの合計 (キャップと呼びましょう) がわかっているので、置換なしタイプ (n=0) の 0 と置換タイプの「キャップ」 (m=3) の組み合わせの数を見つけます。そしてそれらの数を掛け合わせます。次に、置換なしタイプ (n=1) の 1 の組み合わせの数に、置換タイプ (m=2) の組み合わせ「cap-1」を掛けた数を加算します。これを、置換なしタイプ (n=3) に置換タイプ (m=0) の 0 を掛けた「キャップ」の組み合わせを最終的に追加するまで行います (@André Nicolas に感謝します)。
import itertools
from math import factorial as fact
norep = ['A','B','C']
rep = ['1','2','3']
cap = 3 #length of combinations, e.g. cap=3, combo1=123,combo2=A12,etc
combos = 0
for i in range(cap+1):
combnorep = fact(len(norep))/(fact(cap-i)*fact(len(norep)-(cap-i)))
combrep = fact(len(rep)+i-1)/(fact(i)*fact(len(rep)-1))
combos = combos + combnorep*combrep
print combos
この例では、コンボ数は 38 です。次に、すべての組み合わせを出力したいと考えました。これを行うために、すべての置換、すべての置換なし、および 2 つの任意の組み合わせ (n=0、m=3;n=1、m=2; など) の組み合わせを決定しました。これは私が思いついたものです:
for i in range(cap+1):
norepcomb = [j for j in itertools.combinations(norep,i)]
repcomb = [k for k in itertools.combinations_with_replacement(rep,cap-i)]
for l in itertools.product(norepcomb,repcomb):
print list(itertools.chain.from_iterable(l))
を含めるには、置換の組み合わせをリストにnone
含めるだけです。none
特により良い解決策がある場合、またはこれが私が思うように機能しない場合は、これに関するフィードバックをお願いします. ありがとう!