長い間読んでいて、初めて自分が取り組んでいることに対する答えを見つけることができませんでした。
それぞれ6文字の長さの93個の文字列のリストがあります。それらの93個の文字列から、セット内の他の文字列と比較して特定の基準を満たす20個のセットを特定したいと思います。itertools.combinationsはすべての可能な組み合わせを提供しますが、すべての条件を確認する価値があるわけではありません。
たとえば、list[0]とlist[1]を一緒に使用できないために、[list [0]、list [1]など]が失敗した場合、他の18個の文字列が何であっても、セットは毎回失敗します。そしてそれは無駄なチェックのトンです。
現在、これは20個のネストされたforループで動作していますが、より良い/より高速な方法が必要なようです。
for n1 in bclist:
building = [n1]
n2bclist = [bc for bc in bclist if bc not in building]
for n2 in n2bclist: #this is the start of what gets repeated 19 times
building.append(n2)
if test_function(building): #does set fail? (counter intuitive, True when fail, False when pass)
building.remove(n2)
continue
n3bclist = [bc for bc in bclist if bc not in building]
#insert the additional 19 for loops, with n3 in n3, n4 in n4, etc
building.remove(n2)
20番目のforループには、20個のセットが存在する場合でも警告するprintステートメントがあります。forステートメントを使用すると、少なくとも1つの加算が失敗したときにセットを早期にスキップできますが、より大きな組み合わせが失敗したときの記憶はありません。
たとえば失敗するので、どちらのパス[list[0], list[1]]
にスキップします。[list[0], [list[2]]
次は[list[0], list[2], list[1]]
、0と1が再び一緒になり、通過する場合と通過しない場合に移動するため、失敗し[list[0], list[2], list[3]]
ます。私の懸念は、最終的には次のこともテストすることです。
[list[0], list[3], list[2]]
[list[2], list[0], list[3]]
[list[2], list[3], list[0]]
[list[3], list[0], list[2]]
[list[3], list[2], list[0]]
これらの組み合わせはすべて、前の組み合わせと同じ結果になります。基本的に、私はitertools.combinationsの悪魔を交換して、値の順序を気にしないときに値の順序を要因として扱うforループの悪魔に失敗する初期の値のために、失敗することがわかっているセットのすべての組み合わせをテストします。どちらの方法でも、コードが完了するまでにかかる時間が大幅に長くなります。
悪魔を取り除く方法についてのアイデアは大歓迎です。