-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathPercolationModel.py
More file actions
151 lines (106 loc) · 4.84 KB
/
Copy pathPercolationModel.py
File metadata and controls
151 lines (106 loc) · 4.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# Written 05/01/17 by dh4gan
# Object runs a 2D percolation model
# for stellar settlement
import numpy as np
class PercolationModel2D(object):
'''
Object that calculates and displays behaviour of 2D cellular automata
'''
def __init__(self, ni):
'''
Constructor reads:
N = side of grid
produces N x N blank grid
'''
self.N = ni
self.Ntot = self.N*self.N
self.grid = np.zeros((self.N,self.N))
self.nextgrid = np.zeros((self.N,self.N))
self.tested = np.zeros((self.N,self.N))
self.complete = False
def getMooreNeighbourhood(self, i,j):
'''
Returns a set of indices corresponding to the Moore Neighbourhood
(These are the cells immediately adjacent to (i,j), plus those diagonally adjacent)
'''
indices = []
for iadd in range(i-1,i+2):
for jadd in range(j-1, j+2):
if(iadd==i and jadd == j): continue
if(iadd>self.N-1): iadd = iadd - self.N
if(jadd>self.N-1): jadd = jadd - self.N
indices.append([iadd,jadd])
return indices
def getVonNeumannNeighbourhood(self,i,j):
'''
Returns a set of indices corresponding to the Von Neumann Neighbourhood
(These are the cells immediately adjacent to (i,j), but not diagonally adjacent)
'''
indices = []
for iadd in range(i-1,i+2):
if(iadd==i): continue
if(iadd>self.N-1): iadd = iadd - self.N
indices.append([iadd,j])
for jadd in range(j-1,j+2):
if(jadd==j): continue
if(jadd>self.N-1): jadd = jadd - self.N
indices.append([i,jadd])
return indices
def check_complete(self):
ntested = np.sum(self.tested)
if (ntested == self.N*self.N):
self.complete=True
return self.complete
def randomise(self):
'''
Places a random selection of zeros and ones into grid
'''
for i in range(self.N):
for j in range(self.N):
self.grid[i,j] = np.rint(np.random.random())
def randomise_with_symmetry(self):
for i in range(self.N/2):
for j in range(self.N/2):
self.grid[i,j] = np.rint(np.random.random())
self.grid[i+self.N/2,j] = self.grid[i,j+self.N/2] =self.grid[i+self.N/2,j+self.N/2]= self.grid[i,j]
def clear(self, icentre, jcentre, extent):
'''
Clears a space on the grid
'''
for i in range(icentre-extent, icentre+extent):
for j in range(jcentre-extent, jcentre+extent):
if(i>0 and i<self.N and j>0 and j<self.N):
self.grid[i,j] = 0
def updateGrid(self):
'''
Takes the changes queued up on self.nextgrid, and applies them to self.grid
'''
self.grid = np.copy(self.nextgrid)
self.nextgrid = np.zeros((self.N,self.N))
def ApplyPercolationModelRule(self, P):
'''
Constructs the self.nextgrid matrix based on the properties of self.grid
Applies the Percolation Model Rules:
1. Cells attempt to colonise their Moore Neighbourhood with probability P
2. Cells do not make the attempt with probability 1-P
'''
for i in range(self.N):
for j in range(self.N):
if(self.tested[i,j]==1):
self.nextgrid[i,j]=self.grid[i,j]
continue
# If cell contains a coloniser, then decide whether to colonise
if(self.grid[i,j]==1 and self.tested[i,j]==0):
randtest = np.random.rand()
# If colonisation occurs
if(randtest<P):
self.nextgrid[i,j]=1
indices = self.getMooreNeighbourhood(i,j)
for element in indices:
if(self.tested[element[0],element[1]]==1):
continue
if(self.grid[element[0],element[1]]==0):
self.nextgrid[element[0],element[1]]=1
else:
self.nextgrid[i,j]=-1
self.tested[i,j] =1