やりたいこと
- pythonで 条件を満たす(n)個の要素を持つリストを全パターン生成したいです。
例えば、以下のような結果を取得したいです。
[[1, 1, 1, 1, 1, 1, 1, 2, 2, 2], [0, 1, 1, 1, 1, 1, 1, 2, 2, 2], [0, 0, 1, 1, 1, 1, 1, 2, 2, 2], .....]
生成するリストの条件
- 要素数 n=10 (実際には数を50個以上に増やしたい)
- 各要素は0,1,2からなります。
- 0は3個以下しか含まれない。(nの数が大きくなると、この数字も増やします。例えば、int(n*0.1)個程度。)
- 2も3個以下しか含まれない。(同上)
n=10の場合、3**10パターンから、0と2を一定数以上含むパターンのリストを削除するイメージです。
n=15程度なら、実現できる処理は以下のように書きました。
python
1from itertools import product 2 3pattern = [] 4n = 10 # 何列の結果を出すか(n=20くらいでメモリーエラーになる。) 5 6for _ in range(n): 7 pattern.append([0,1,2]) 8 9data = list(product(*pattern)) # この処理が重いです。 10 11# dataは、例えば、例: [[0, 0, 1, 1, 1, 1, 1, 2, 2, 2], [0, 1, 1, 1, 1, 1, 1, 2, 2, 2].....]のようなデータです。 12# dataから(ここでは例として)、"0が3個以上"、"2が3個以上"含むリストを、削除します。 13 14result = [] 15 16for row in data: 17 if row.count(0) >= 3 or row.count(2) >= 3: 18 continue 19 result.append(row) 20 21print(resutl)
この方法ですと、nが大きくなると計算しきれずメモリーエラーになってしまいます。n=10(310)ではすぐに計算できても、20では(320)で手元のPCではエラーを起こします。
ただ、例えば、n=10で計算した場合に、総当りで出したdataは59049個のなのに対して、必要なデータをピックアップしたresultは2181個と相当少なくなります。なので、総当たりせずに、resultを直接出せれば、nが大きくなってもある程度なら計算できるのでは?と考えています。
この処理の中で最も重いのは、
data = list(product(*pattern))
です。
ここで総当りしてしまっているのが無駄な作業で、0や2を含む数が規定より多い場合に、処理をしないようにスキップできればいいはずです。
仮説
例えば、
- はじめに[1,1,1,1,1,1...]を作って、0をn個、2をm個、代入する、という発想もありなのかな?と考えはしたものの、コードに落とし込めません。。
- ビット演算を使う??
- numpyで処理すれば多少は早くなる?
ただ、正解にたどり着けません。。。
教えて頂けると幸いです。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2022/11/18 07:18
2022/11/18 07:21
2022/11/18 08:28