質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

3回答

624閲覧

計算の効率化 ネストが複雑になる

s_kj

総合スコア31

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2020/07/27 13:24

編集2020/07/27 14:22

プログラミング初学者です。
*編集依頼の内容を〜〜〜部分に追記しています。

複数のリストの中身の組合せを作成し、別の新規なリストを作成しようとしています。
下記のようなコードを実行したところ私のPCでは所要時間550秒でした。

このスクリプトではrepeat=6にしていますが、さらに複雑な計算をしたい希望があります。
具体的には、2つ目のコードのようにrepeat=10にしたり、後半部分の「for x,y in itertools.product(seq_1,seq_2)」をseq_3,seq_4を追加した上で「for w,x,y,z in itertools.product(seq_1,seq_2,seq_3,seq_4)」などネストをさらに深くしたいです。

概算したのですが、
すでに1つ目のコードをrepeat=10にしただけでも1年ぐらいかかりそうです。

何か方法はあるのでしょうか。
今回の計算を達成することは不可能でも短縮できる方法があれば、ご教示いただけますと幸いです。

編集内容
〜〜〜〜
解きたい問題
「」「」「」・・・・「」「」「」のように20個の箱が順番に並んでいて、各々その箱の中に●と▲の2つの石を入れます。
この●と▲の石には1〜4までの数字が書かれています。
箱「」には順番があり左から1〜20までの箱番号がふられています。
石の順番は問いません。

この箱の並びを1つの配列と定義します。
この場合、配列の種類は4の20乗通り×4の20乗通りになります。

20個の箱が並んだ配列は、合計で2つあります。
それらを配列①、配列②と定義します。
配列①と配列②で存在する全ての組み合わせを作り出して、以降の計算を行いたいと思っています。

*ここからの内容は質問の範囲外です。補足です。
配列①と配列②から1つずつ箱「」を取り出して、その箱の中にある4つの数字(●2つと▲2つ)と掛け合わせます(値1)。
さらに配列①から箱を取り出した位置の箱番号と配列②から箱を取り出した位置の箱番号の差分をとり、その差分を値1にかけて値2を得ます。

全ての配列①と配列②の中の組み合わせで、かつその各々の組み合わせの中で箱を取り出す位置に応じた値2を網羅的に取得したいと考えています。
〜〜〜〜

コード1

python

1import time 2import itertools 3 4time_start = time.time() 5 6txt = [1,2,3,4] 7 8seq_1 = list(itertools.product(txt, repeat=6)) 9seq_2 = list(itertools.product(txt, repeat=6)) 10target = [] 11 12for x,y in itertools.product(seq_1,seq_2): 13 a = [x,y] 14 target.append(a) 15 16print(target) 17 18time_end = time.time() 19 20print('所要時間:{}'.format(time_end-time_start))

コード2 目標

python

1import time 2import itertools 3 4time_start = time.time() 5 6txt = [1,2,3,4] 7 8seq_1 = list(itertools.product(txt, repeat=10)) 9seq_2 = list(itertools.product(txt, repeat=10)) 10seq_3 = list(itertools.product(txt, repeat=10)) 11seq_4 = list(itertools.product(txt, repeat=10)) 12target = [] 13 14for w,x,y,z in itertools.product(seq_1,seq_2,seq_3,seq_4): 15 a = [w,x,y,z] 16 target.append(a) 17 18print(target) 19 20time_end = time.time() 21 22print('所要時間:{}'.format(time_end-time_start))

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

can110

2020/07/27 13:39

もともとの解きたい問題を提示すると、そもそもループ回さなくてもよい方法が提案されるかもしれません。
guest

回答3

0

ベストアンサー

この場合、配列の種類は4の20乗通り×4の20乗通りになります。

この時点で既に場合の数は2の80乗通り~10の24乗通りあります。たとえばスーパーコンピュータを使って1PFLOPS(10の15乗演算/秒)が可能とすると、10の9乗秒、すなわち約32年弱で計算できることになります。

したがって元の課題の計算量を削減することから始めるのが良いと思います。

投稿2020/07/27 16:07

yymmt

総合スコア1615

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

s_kj

2020/07/28 11:40

コメントありがとうございます。 実行内容を再考したいと思います。 ベストアンサーにさせていただきました。
guest

0

値1のバリエーションが 4^4 = 256 通り
値2のバリエーションが 値1×20通り(±含めても40通り) = 1万通り程度

4^20^2のマトリクスを作るより、必要に応じて求めたほうが早いのでは?

投稿2020/07/27 16:22

Kaleidoscope

総合スコア257

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

s_kj

2020/07/28 11:39

コメントありがとうございます。 実行内容を再考したいと思います。
guest

0

意図がよく分からないですが、下記ではダメなのでしょうか。

python

1import itertools 2 3txt = ['A','B','C','D'] 4 5seq_1 = list(itertools.product(txt, repeat=6)) 6seq_2 = list(itertools.product(txt, repeat=6)) 7target = list(itertools.product(seq1, seq2))

質問に書かれたのとどうしても同じ出力が得たい場合はリスト内包表記を使って下記でどうでしょうか。
for文を使うよりは現実的かと思います。

python

1target = [[x,y] for x,y in itertools.product(seq1, seq2)]

投稿2020/07/27 14:08

tenkoh

総合スコア51

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

s_kj

2020/07/28 11:41

コメントありがとうございます。 少なくともprint関数を使用しないだけでも速くなることがわかりました。 大変参考になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問