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

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

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

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

Q&A

解決済

2回答

1320閲覧

Pythonのコードを実行しようとしているが計算がとても遅い

suugaku_nyumon

総合スコア37

Python 3.x

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

0グッド

1クリップ

投稿2020/11/01 03:24

質問内容

以下のコードを実行しようとしているのですが、Windows Powershellで「python coronatest1.py」と書いて実行してみると、I(28)、R(28)の値あたりから計算速度が異常に遅くなり、I(31)、R(31)の値が出たあたりからは値が数分待っても表示されないので困っています。

このプログラムでI(91)、R(91)、I(100)、R(100)の値を出そうとしているのですが、計算を早くするコツとしてどのようなことがありますでしょうか?

coronatest1

1import math 2import numpy as np 3 4def I(t): 5 if t >= 0 and t <= 14: 6 return 0 7 if t == 15: 8 return 2 / 14000000 9 else: 10 return I(t-1) + B(t-1) * I(t-1) * S(t-1) - B(t-15) * I(t-15) * S(t-15) 11 12def S(t): 13 if t >= 0 and t <= 14: 14 return 1 15 if t == 15: 16 return (14000000 - 2) / 14000000 17 else: 18 return S(t-1) - B(t-1) * I(t-1) * S(t-1) 19 20def R(t): 21 if t >= 0 and t <= 14: 22 return 0 23 else: 24 return R(t-1) + B(t-15) * I(t-15) * S(t-15) 25 26def B(t): 27 if t >= 0 and t <= 86: 28 return 0.16 29 if t >= 87 and t <= 97: 30 return B(t-1) * 0.91 31 if t >= 98 and t <= 120: 32 return B(t-1) * 0.97 33 else: 34 return 0.16 35 36print(I(91)) 37print(R(91)) 38print(I(100)) 39print(R(100))

試したこと

私は実行結果の桁数が多いため、計算速度が遅いと思いました。なので、decimalモジュールを使っています。
具体的にはdecimal.getcontext().prec = 3とすることで有効数字を3桁にして、例えばdecimal.Decimal(I(t))とすることで、値の桁数を小さくすることで計算を早くしようと考えました。

しかしdecimalモジュールを使っても結果は変わらず、またI(28)やR(28)あたりで値の出力が非常に遅くなり、I(31)やR(31)のあたりになると出力が止まりました。

コードの内容

このコードは以下の式に基づいて計算を実行しています。
I(t) = I(t-1) + B(t-1)I(t-1)S(t-1) - B(t-15)I(t-15)R(t-15)
S(t) = S(t-1) - B(t-1)I(t-1)S(t-1)
R(t) = R(t-1) + B(t-15)I(t-15)S(t-15)
B(t)は以下の規則に従う。
0≦t≦86の時はB(t)=0.16
87≦t≦97の時はB(t)=0.91B(t-1)を満たす
98≦t≦120の時はB(t)=0.97B(t-1)を満たす
121≦tの時はB(t)=0.16を満たす

I(t)、R(t)は0≦t≦14の時は0であるとして、S(t)はt=0の時は1とする。

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

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

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

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

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

guest

回答2

0

ベストアンサー

再帰呼び出しが多いので、関数のキャッシュを取ると良いと思います。

Python

1... 2import functools 3 4@functools.lru_cache 5def I(t): 6 ... 7 8@functools.lru_cache 9def S(t): 10 ... 11 12@functools.lru_cache 13def R(t): 14 ... 15 16@functools.lru_cache 17def B(t): 18 ... 19 20print(I(91)) 21print(R(91)) 22print(I(100)) 23print(R(100))

参考functools --- 高階関数と呼び出し可能オブジェクトの操作 — Python 3.9.0 ドキュメント

投稿2020/11/01 03:30

LouiS0616

総合スコア35660

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

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

suugaku_nyumon

2020/11/01 06:12

キャッシュを取ってみたところ、計算が非常に早くなりました。 ご回答ありがとうございます。
guest

0

再帰が深く、かつ同じ計算が何度もなされるのでcacheを使ってみてはどうでしょうか。
https://docs.python.org/3/library/functools.html

投稿2020/11/01 03:31

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

suugaku_nyumon

2020/11/01 06:12

キャッシュを取ってみたところ、計算が非常に早くなりました。 ご回答ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問