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

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

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

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

解決済

数値計算の式をまとめる方法

suugaku_nyumon
suugaku_nyumon

総合スコア37

Python 3.x

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

2回答

0リアクション

0クリップ

189閲覧

投稿2018/12/10 17:09

質問内容

2次元の感染症のセルオートマトンを書いてコードは書けていたのですが、コードのdef execCellの部分がとても長くなっており、式が羅列している状態で見づらいので短い表現に変えられるならば変えたいと思っているのですが、自分では思いつきません。

下のコードのexecCellを短くまとめるにはどうすればよいのでしょうか?
###execCellの内容
縦31マス、横31マスのセルで考えています。そのセルに動物Aと動物Bがおり、ウイルスの感染の広がりはどうなのかをセルオートマトンでモデル化しようとしています。

A[n][i][j]はnステップ目における(i,j)のセルの状態値を表しており、1であれば感染した動物A、2であれば感染していない動物A、3であれば感染した動物B、4であれば感染していない動物Bを表しています。

ここで動物の移動は考えておらず、動物の状態=セルの状態で考えています。

ここで感染度と感染確率を定義しますが、感染確率に関しては動物Aから動物Aではp_cc=0.25、動物Bから動物Aではp_bc=0.75、動物Aから動物Bでは0.10、動物Bから動物Bでは0.40と考えています。

また2重感染は考えておらず、感染していない個体のみ他の縦か横で隣接するマスからうつされると仮定します。alphaは自己回復率で、隣接する個体からの感染が無い場合、次のステップの感染度は今のステップの自身の感染度の(1-α)倍となるように式を設定しています。

なぜ式が長くなったかというと、まず自身が感染しているかどうかの場合分けと、そして自身が感染していない場合に隣接する4つのマスのそれぞれの状態を場合分けで考え、さらに感染度によって感染しているか否か、次の状態を考えているためそこでも場合分けが生じます。

せめて隣接するマスの場合分けを少なくできればよいと思ったのですが、ためしに自分がやってみるとプログラム自体が変わってしまったので、どうにかプログラムを変えずに変形できるかと悩んでおりました。

自身の次のステップの感染度の計算は

(自身の今のステップの感染度)×(1-回復率)+(隣接する4マスのそれぞれの感染度に、感染確率を掛け合わせたものの総和)

で計算しています。

コード

python3

from tkinter import * import time import tkinter as tk import random import math #配列の宣言 def array2(N1,N2): return [[0 for j in range(N2)]for k in range(N1)] def array3(N1,N2,N3): return [array2(N2,N3)for k in range(N1)] #セルの初期設定 def initdt(): A=array3(1000,31,31) B=array3(1000,31,31) for i in range(1,31): for j in range(1,31): if (i == 15 and j == 15): A[0][i][j] = 1 B[0][i][j] = 1 else: r_i=random.random() if (r_i <= 0.5): A[0][i][j] = 2 B[0][i][j] = 0 if (r_i > 0.5): A[0][i][j] = 4 B[0][i][j] = 0 return A , B #セルオートマトンの実行 def execCell(A,B,i1): i2 = 1 + i1 for i in range(1,30): for j in range(1,30): alpha = 0.50 p_cc = 0.25 p_bc = 0.75 p_cb = 0.10 p_bb = 0.40 a = 0.60 if A[i1][i][j] == 1: B[i2][i][j] = (1 - alpha) * B[i1][i][j] if (B[i2][i][j] >= 0 and B[i2][i][j] < a): A[i2][i][j] = 2 if (B[i2][i][j] >= a and B[i2][i][j] <= 1.0): A[i2][i][j] = 1 if A[i1][i][j] == 2: if ((A[i1][i+1][j] == 1 or A[i1][i+1][j] == 2) and (A[i1][i-1][j] == 1 or A[i1][i-1][j] == 2) and (A[i1][i][j+1] == 1 or A[i1][i][j+1] == 2) and (A[i1][i][j-1] == 1 or A[i1][i][j-1] == 2)): B[i2][i][j] = (1 - alpha) * B[i1][i][j] + p_cc * B[i1][i+1][j] + p_cc * B[i1][i-1][j] + p_cc * B[i1][i][j+1] + p_cc * B[i1][i][j-1] if ((A[i1][i+1][j] == 3 or A[i1][i+1][j] == 4) and (A[i1][i-1][j] == 1 or A[i1][i-1][j] == 2) and (A[i1][i][j+1] == 1 or A[i1][i][j+1] == 2) and (A[i1][i][j-1] == 1 or A[i1][i][j-1] == 2)): B[i2][i][j] = (1 - alpha) * B[i1][i][j] + p_bc * B[i1][i+1][j] + p_cc * B[i1][i-1][j] + p_cc * B[i1][i][j+1] + p_cc * B[i1][i][j-1] if ((A[i1][i+1][j] == 1 or A[i1][i+1][j] == 2) and (A[i1][i-1][j] == 3 or A[i1][i-1][j] == 4) and (A[i1][i][j+1] == 1 or A[i1][i][j+1] == 2) and (A[i1][i][j-1] == 1 or A[i1][i][j-1] == 2)): B[i2][i][j] = (1 - alpha) * B[i1][i][j] + p_cc * B[i1][i+1][j] + p_bc * B[i1][i-1][j] + p_cc * B[i1][i][j+1] + p_cc * B[i1][i][j-1] if ((A[i1][i+1][j] == 1 or A[i1][i+1][j] == 2) and (A[i1][i-1][j] == 1 or A[i1][i-1][j] == 2) and (A[i1][i][j+1] == 3 or A[i1][i][j+1] == 4) and (A[i1][i][j-1] == 1 or A[i1][i][j-1] == 2)): B[i2][i][j] = (1 - alpha) * B[i1][i][j] + p_cc * B[i1][i+1][j] + p_cc * B[i1][i-1][j] + p_bc * B[i1][i][j+1] + p_cc * B[i1][i][j-1] if ((A[i1][i+1][j] == 1 or A[i1][i+1][j] == 2) and (A[i1][i-1][j] == 1 or A[i1][i-1][j] == 2) and (A[i1][i][j+1] == 1 or A[i1][i][j+1] == 2) and (A[i1][i][j-1] == 3 or A[i1][i][j-1] == 4)): B[i2][i][j] = (1 - alpha) * B[i1][i][j] + p_cc * B[i1][i+1][j] + p_cc * B[i1][i-1][j] + p_cc * B[i1][i][j+1] + p_bc * B[i1][i][j-1] if ((A[i1][i+1][j] == 3 or A[i1][i+1][j] == 4) and (A[i1][i-1][j] == 3 or A[i1][i-1][j] == 4) and (A[i1][i][j+1] == 1 or A[i1][i][j+1] == 2) and (A[i1][i][j-1] == 1 or A[i1][i][j-1] == 2)): B[i2][i][j] = (1 - alpha) * B[i1][i][j] + p_bc * B[i1][i+1][j] + p_bc * B[i1][i-1][j] + p_cc * B[i1][i][j+1] + p_cc * B[i1][i][j-1] if ((A[i1][i+1][j] == 3 or A[i1][i+1][j] == 4) and (A[i1][i-1][j] == 1 or A[i1][i-1][j] == 2) and (A[i1][i][j+1] == 3 or A[i1][i][j+1] == 4) and (A[i1][i][j-1] == 1 or A[i1][i][j-1] == 2)): B[i2][i][j] = (1 - alpha) * B[i1][i][j] + p_bc * B[i1][i+1][j] + p_cc * B[i1][i-1][j] + p_bc * B[i1][i][j+1] + p_cc * B[i1][i][j-1] if ((A[i1][i+1][j] == 3 or A[i1][i+1][j] == 4) and (A[i1][i-1][j] == 1 or A[i1][i-1][j] == 2) and (A[i1][i][j+1] == 1 or A[i1][i][j+1] == 2) and (A[i1][i][j-1] == 3 or A[i1][i][j-1] == 4)): B[i2][i][j] = (1 - alpha) * B[i1][i][j] + p_bc * B[i1][i+1][j] + p_cc * B[i1][i-1][j] + p_cc * B[i1][i][j+1] + p_bc * B[i1][i][j-1] if ((A[i1][i+1][j] == 1 or A[i1][i+1][j] == 2) and (A[i1][i-1][j] == 3 or A[i1][i-1][j] == 4) and (A[i1][i][j+1] == 3 or A[i1][i][j+1] == 4) and (A[i1][i][j-1] == 1 or A[i1][i][j-1] == 2)): B[i2][i][j] = (1 - alpha) * B[i1][i][j] + p_cc * B[i1][i+1][j] + p_bc * B[i1][i-1][j] + p_bc * B[i1][i][j+1] + p_cc * B[i1][i][j-1] if ((A[i1][i+1][j] == 1 or A[i1][i+1][j] == 2) and (A[i1][i-1][j] == 3 or A[i1][i-1][j] == 4) and (A[i1][i][j+1] == 1 or A[i1][i][j+1] == 2) and (A[i1][i][j-1] == 3 or A[i1][i][j-1] == 4)): B[i2][i][j] = (1 - alpha) * B[i1][i][j] + p_cc * B[i1][i+1][j] + p_bc * B[i1][i-1][j] + p_cc * B[i1][i][j+1] + p_bc * B[i1][i][j-1] if ((A[i1][i+1][j] == 1 or A[i1][i+1][j] == 2) and (A[i1][i-1][j] == 1 or A[i1][i-1][j] == 2) and (A[i1][i][j+1] == 3 or A[i1][i][j+1] == 4) and (A[i1][i][j-1] == 3 or A[i1][i][j-1] == 4)): B[i2][i][j] = (1 - alpha) * B[i1][i][j] + p_cc * B[i1][i+1][j] + p_cc * B[i1][i-1][j] + p_bc * B[i1][i][j+1] + p_bc * B[i1][i][j-1] if ((A[i1][i+1][j] == 3 or A[i1][i+1][j] == 4) and (A[i1][i-1][j] == 3 or A[i1][i-1][j] == 4) and (A[i1][i][j+1] == 3 or A[i1][i][j+1] == 4) and (A[i1][i][j-1] == 1 or A[i1][i][j-1] == 2)): B[i2][i][j] = (1 - alpha) * B[i1][i][j] + p_bc * B[i1][i+1][j] + p_bc * B[i1][i-1][j] + p_bc * B[i1][i][j+1] + p_cc * B[i1][i][j-1] if ((A[i1][i+1][j] == 3 or A[i1][i+1][j] == 4) and (A[i1][i-1][j] == 3 or A[i1][i-1][j] == 4) and (A[i1][i][j+1] == 1 or A[i1][i][j+1] == 2) and (A[i1][i][j-1] == 3 or A[i1][i][j-1] == 4)): B[i2][i][j] = (1 - alpha) * B[i1][i][j] + p_bc * B[i1][i+1][j] + p_bc * B[i1][i-1][j] + p_cc * B[i1][i][j+1] + p_bc * B[i1][i][j-1] if ((A[i1][i+1][j] == 3 or A[i1][i+1][j] == 4) and (A[i1][i-1][j] == 1 or A[i1][i-1][j] == 2) and (A[i1][i][j+1] == 3 or A[i1][i][j+1] == 4) and (A[i1][i][j-1] == 3 or A[i1][i][j-1] == 4)): B[i2][i][j] = (1 - alpha) * B[i1][i][j] + p_bc * B[i1][i+1][j] + p_cc * B[i1][i-1][j] + p_bc * B[i1][i][j+1] + p_bc * B[i1][i][j-1] if ((A[i1][i+1][j] == 1 or A[i1][i+1][j] == 2) and (A[i1][i-1][j] == 3 or A[i1][i-1][j] == 4) and (A[i1][i][j+1] == 3 or A[i1][i][j+1] == 4) and (A[i1][i][j-1] == 3 or A[i1][i][j-1] == 4)): B[i2][i][j] = (1 - alpha) * B[i1][i][j] + p_cc * B[i1][i+1][j] + p_bc * B[i1][i-1][j] + p_bc * B[i1][i][j+1] + p_bc * B[i1][i][j-1] if ((A[i1][i+1][j] == 3 or A[i1][i+1][j] == 4) and (A[i1][i-1][j] == 3 or A[i1][i-1][j] == 4) and (A[i1][i][j+1] == 3 or A[i1][i][j+1] == 4) and (A[i1][i][j-1] == 3 or A[i1][i][j-1] == 4)): B[i2][i][j] = (1 - alpha) * B[i1][i][j] + p_bc * B[i1][i+1][j] + p_bc * B[i1][i-1][j] + p_bc * B[i1][i][j+1] + p_bc * B[i1][i][j-1] if (B[i2][i][j] >= 0 and B[i2][i][j] < a): A[i2][i][j] = 2 if (B[i2][i][j] >= a and B[i2][i][j] <= 1.0): A[i2][i][j] = 1 if (B[i2][i][j] > 1.0): A[i2][i][j] = 1 B[i2][i][j] = 1.0 (ここから先は文字数が10000字を超えるので省略) #セルの位置決めとIDの設定 def drawCell(canvas,A,k): x2=0 CID=array2(31,31) for i in range(1,30): x1=x2 x2=x1+20 y2=0 for j in range(1,30): y1=y2 y2=y1+20 CID[i][j]=canvas.create_rectangle(x1,y1,x2,y2,fill='black') return CID #セルの色設定 def modifyCell(canvas,A,k,CID): CL=['black','#ffffff','#ff0000','#ffffff','#0000ff'] for i in range(1,30): for j in range(1,30): canvas.itemconfig(CID[i][j],fill=CL[A[k][i][j]]) canvas.itemconfig(CID[i][j],outline=CL[A[k][i][j]]) #Tk初期設定 def initTk(): tk=Tk(); tk.title("2D Cell Automaton"); tk.resizable(0,0) return tk #画面キャプチャ用 def leftMouseDown(event): global canvas, A,k,CID modifyCell(canvas,A,k,CID) execCell(A,B,k) #実行メイン A,B=initdt() root=initTk() canvas=Canvas(root,width=580,height=580,highlightthickness=0) canvas.pack() CID=drawCell(canvas,A,0) k=0 def animate(): global k modifyCell(canvas, A, k, CID) execCell(A,B,k) k = 1 + k root.after(1000, animate) root.after(1000, animate) root.mainloop()

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
86.12%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Python 3.x

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。