質問内容
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
1from tkinter import * 2import time 3import tkinter as tk 4import random 5import math 6#配列の宣言 7def array2(N1,N2): 8 return [[0 for j in range(N2)]for k in range(N1)] 9def array3(N1,N2,N3): 10 return [array2(N2,N3)for k in range(N1)] 11#セルの初期設定 12def initdt(): 13 A=array3(1000,31,31) 14 B=array3(1000,31,31) 15 for i in range(1,31): 16 for j in range(1,31): 17 if (i == 15 and j == 15): 18 A[0][i][j] = 1 19 B[0][i][j] = 1 20 else: 21 r_i=random.random() 22 if (r_i <= 0.5): 23 A[0][i][j] = 2 24 B[0][i][j] = 0 25 if (r_i > 0.5): 26 A[0][i][j] = 4 27 B[0][i][j] = 0 28 return A , B 29#セルオートマトンの実行 30def execCell(A,B,i1): 31 i2 = 1 + i1 32 for i in range(1,30): 33 for j in range(1,30): 34 alpha = 0.50 35 p_cc = 0.25 36 p_bc = 0.75 37 p_cb = 0.10 38 p_bb = 0.40 39 a = 0.60 40 if A[i1][i][j] == 1: 41 B[i2][i][j] = (1 - alpha) * B[i1][i][j] 42 if (B[i2][i][j] >= 0 and B[i2][i][j] < a): 43 A[i2][i][j] = 2 44 if (B[i2][i][j] >= a and B[i2][i][j] <= 1.0): 45 A[i2][i][j] = 1 46 if A[i1][i][j] == 2: 47 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)): 48 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] 49 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)): 50 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] 51 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)): 52 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] 53 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)): 54 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] 55 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)): 56 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] 57 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)): 58 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] 59 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)): 60 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] 61 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)): 62 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] 63 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)): 64 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] 65 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)): 66 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] 67 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)): 68 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] 69 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)): 70 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] 71 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)): 72 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] 73 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)): 74 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] 75 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)): 76 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] 77 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)): 78 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] 79 if (B[i2][i][j] >= 0 and B[i2][i][j] < a): 80 A[i2][i][j] = 2 81 if (B[i2][i][j] >= a and B[i2][i][j] <= 1.0): 82 A[i2][i][j] = 1 83 if (B[i2][i][j] > 1.0): 84 A[i2][i][j] = 1 85 B[i2][i][j] = 1.0 86 (ここから先は文字数が10000字を超えるので省略) 87 88#セルの位置決めとIDの設定 89def drawCell(canvas,A,k): 90 x2=0 91 CID=array2(31,31) 92 for i in range(1,30): 93 x1=x2 94 x2=x1+20 95 y2=0 96 for j in range(1,30): 97 y1=y2 98 y2=y1+20 99 CID[i][j]=canvas.create_rectangle(x1,y1,x2,y2,fill='black') 100 return CID 101#セルの色設定 102def modifyCell(canvas,A,k,CID): 103 CL=['black','#ffffff','#ff0000','#ffffff','#0000ff'] 104 for i in range(1,30): 105 for j in range(1,30): 106 canvas.itemconfig(CID[i][j],fill=CL[A[k][i][j]]) 107 canvas.itemconfig(CID[i][j],outline=CL[A[k][i][j]]) 108#Tk初期設定 109def initTk(): 110 tk=Tk(); tk.title("2D Cell Automaton"); tk.resizable(0,0) 111 return tk 112#画面キャプチャ用 113def leftMouseDown(event): 114 global canvas, A,k,CID 115 modifyCell(canvas,A,k,CID) 116 execCell(A,B,k) 117#実行メイン 118A,B=initdt() 119root=initTk() 120canvas=Canvas(root,width=580,height=580,highlightthickness=0) 121canvas.pack() 122CID=drawCell(canvas,A,0) 123k=0 124 125def animate(): 126 global k 127 modifyCell(canvas, A, k, CID) 128 execCell(A,B,k) 129 k = 1 + k 130 root.after(1000, animate) 131 132root.after(1000, animate) 133root.mainloop()

回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/12/11 14:33