-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexSolution.py
More file actions
340 lines (301 loc) · 14.3 KB
/
Copy pathexSolution.py
File metadata and controls
340 lines (301 loc) · 14.3 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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
#Author : George Dozorets Date: 23/7/2021
# Simulates fire of a machinegun from diffrent distances
#
# Future Development:
# (1) Real time simulation of each shoot
# (2) 3d plot
# (3) Lowering the time and space complexity
# (4) Add propreties to the objects
############################################################################################
#this experiants simulats cannon which fires from variaty of distances (D)
#the experiment returns N times. for each number of burst calculates the AVG of hit to target
#target size could be changed by suited function, default size of 1 m^3
#distance steps by defulat 1 KM, if needed could be changed by suited fucntion
#to inital experiments write:
#exp = experiments(N,D,B) - defines parameters
#exp.runAllSimulates() - run the simulation
#exp.plotAllSimulates() - ploting all simulations by bursts length as function of AVG hits in target
#N - number of experiments for each distance and number of burst
#D - range for 1 kilomter to D kilometer
#B - Burst -Number of shots
#returns experiments object
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
class experiments():
def __init__(self,N,D,B):
self.N = N
self.D = D
self.B = B
self.targetSize = 1 #default value
self.maxTargetX = self.targetSize * (0.5)
self.minTargetX = self.targetSize * (-0.5)
self.maxTargetY = self.targetSize * (0.5)
self.minTargetY = self.targetSize * (-0.5)
self.CError=0.1
self.cons=1.177
self.REror=0.2
self.distanceStep = 1 #default step size of distance in KM
self.expermientList = []
#function to change target size
#targetSize - by m^3
def setTargetSize(self,targetSize):
self.targetSize = targetSize
self.maxTargetX = targetSize * (0.5)
self.minTargetX = targetSize * (-0.5)
self.maxTargetY = targetSize * (0.5)
self.minTargetY = targetSize * (-0.5)
def setCError(self,newError):
self.CError = newError
def setConstant(self,newConstant):
self.cons = newConstant
def setRandomError(self,newRandomError):
self.DEror = newRandomError
#function to rull simulates of the experiments
def runAllSimulates(self):
if(not len(self.expermientList)):
self.expermientList = [experiment(self.N,i,self.B) for i in range(1,self.D+1,self.distanceStep)]
for d in range(self.D):
self.expermientList[d].aim()
self.expermientList[d].fire()
self.expermientList[d].calculateResults()
#function to plot the resulats of the experiments
#experiemtns must run first
def plotAllSimulates(self,saveFig=False):
if(len(self.expermientList)):
plt.figure(figsize=(10,7))
colors = sns.color_palette("rocket", n_colors=self.D)
for d in range(self.D):
plt.scatter(range(self.B),self.expermientList[d].TotalMeanHitsPerBrust,label=str(d+1)+" KM",color=colors[d])
plt.plot([0,self.B],[1,1],label='AVG hits = 1',color='blue')
plt.legend()
plt.xlabel("Brust length")
plt.ylabel("AVG Number of hits")
plt.title("N="+str(self.N)+" D="+str(self.D)+" B="+str(self.B))
if(saveFig): plt.savefig('resualt1N{}.png'.format(self.N))
plt.show()
else:
print("Run the experiments object first with runAllSimulates()")
def plotAllSimulates2(self,saveFig=False):
if(len(self.expermientList)):
plt.figure(figsize=(10,7))
colors = sns.color_palette("rocket", n_colors=self.B)
for b in range(self.B):
plt.plot(self.getAVGHitsPerBrustLength(b),range(1,self.D+1),label="Brust len: "+str(b+1),color=colors[b])
plt.plot([1,1],[0,self.D],label='AVG hits = 1',color='blue')
plt.legend()
plt.xlabel("AVG number of hits")
plt.ylabel("Kilometers")
plt.title("N="+str(self.N)+" D="+str(self.D)+" B="+str(self.B))
if(saveFig): plt.savefig('resualt2N{}.png'.format(self.N))
plt.show()
else:
print("Run the experiments object first with runAllSimulates()")
#method which return array of AVG hits per brust length
#arr[i] means KM
def getAVGHitsPerBrustLength(self,bl):
tmpArr = []
for k in range(self.D):
tmpArr.append(self.expermientList[k].TotalMeanHitsPerBrust[bl])
return tmpArr
#method return min brust needed to hit target once from given km
def getMinBrustForOneHit(self,km):
for b in range(self.B):
if(self.expermientList[km].TotalMeanHitsPerBrust[b]>=1):
return b+1
#method which return list of min burst needed for each of the km in range
def getListOfMinBrustForOneHitByKm(self):
tmpArr = []
for k in range(self.D):
if(self.getMinBrustForOneHit(k)):
tmpArr.append(self.getMinBrustForOneHit(k))
else:
tmpArr.append(-1)
return tmpArr
#plost resulats of min brust length needed to hit target one from each of the km in range
def plotAllSimulates3(self,saveFig=False):
if(len(self.expermientList)):
plt.figure(figsize=(10,7))
colors = sns.color_palette("rocket", n_colors=self.D+2)
colors = [colors[i+2] for i in self.getListOfMinBrustForOneHitByKm()]
plt.scatter(range(1,self.D+1),self.getListOfMinBrustForOneHitByKm(),c=colors)
plt.xlabel("Kilometers")
plt.ylabel("Brust Length")
plt.title("Min brust to hit target in AVG one time\n"+"N="+str(self.N)+" D="+str(self.D)+" B="+str(self.B))
if(saveFig): plt.savefig('resualt3N{}.png'.format(self.N))
plt.show()
# single experiment object
# this object inhirates from experiments
# listOfBrusts - contains list of brusts by length
# TotalMeanHitsPerBrust - total mean hits per brusts group length
class experiment(experiments):
def __init__(self,N,D,B):
experiments.__init__(self,N,D,B)
self.listOfBrusts = []
self.TotalMeanHitsPerBrust = []
#function which creates list of brusts
#used in aim fucntion
def createBrusts(self):
if(not len(self.listOfBrusts)):
self.listOfBrusts = [brusts(self.N,self.D,i+1) for i in range(self.B)]
#function to aim the brusts
#to determine common error x1,y1 values
def aim(self):
self.createBrusts()
for i in range(self.B):
self.listOfBrusts[i].createSingleLengthBrusts()
#function to fire the brusts
#determines random error x2,y2 values
def fire(self):
if(len(self.listOfBrusts)):
for i in range(self.B):
for j in range(self.N):
self.listOfBrusts[i].brustList[j].fireBrust()
else:
print("must aim first")
#function to plot common error of all brusts
def plotCommonErrorAllBrusts(self):
if(len(self.listOfBrusts)):
plt.figure(figsize=(10,7))
colors = sns.color_palette("rocket", n_colors=self.B)
for i in range(self.B):
self.listOfBrusts[i].calBrustsCECor()
plt.scatter(self.listOfBrusts[i].BrustCEcorX,self.listOfBrusts[i].BrustCEcorY,marker='+',label="brust of "+str(self.listOfBrusts[i].B),color=colors[i])
plt.legend()
plt.title("Common error by brusts ,Distance = "+str(self.D)+" KM")
plt.scatter(0,0,s=2000,marker='+',color='blue')
else:
print("must aim and fire first")
#function to plot all shots
def plotAllShots(self,CEFlag=True):
if(len(self.listOfBrusts)):
plt.figure(figsize=(15,15))
colors = sns.color_palette("rocket", n_colors=self.B)
#target borders
plt.plot([self.minTargetX,self.minTargetX],[self.minTargetY,self.maxTargetY],color='blue') #left
plt.plot([self.minTargetX,self.maxTargetX],[self.maxTargetY,self.maxTargetY],color='blue') #up
plt.plot([self.maxTargetX,self.maxTargetX],[self.minTargetY,self.maxTargetY],color='blue') #right
plt.plot([self.minTargetX,self.maxTargetX],[self.minTargetY,self.minTargetY],color='blue') #down
for i in range(self.B):
self.listOfBrusts[i].calBrustsCECor()
if(CEFlag):
plt.scatter(self.listOfBrusts[i].BrustCEcorX,self.listOfBrusts[i].BrustCEcorY,s=100,marker='+',label="burst of "+str(self.listOfBrusts[i].B),color=colors[i])
for j in range(self.N):
self.listOfBrusts[i].brustList[j].calShootsCor()
plt.scatter(self.listOfBrusts[i].brustList[j].ShotsX,self.listOfBrusts[i].brustList[j].ShotsY,s=10,alpha=0.1,color=colors[i])
if(CEFlag):
plt.legend()
plt.title("All shoots distribution by brusts ,Distance = "+str(self.D)+" KM")
plt.scatter(0,0,s=2000,marker='+',color='blue')
else:
print("must aim and fire first")
#function which calculates the resualts of the expirement
#stors them into list 'TotalMeanHitsPerBrust'
def calculateResults(self):
if(not len(self.TotalMeanHitsPerBrust)):
for i in range(self.B):
self.listOfBrusts[i].calBrusMeanNumberOfHits()
self.TotalMeanHitsPerBrust.append(self.listOfBrusts[i].BrustMeanNumberOfHits)
#function to basic plot the resualts
def plotResults(self):
if(len(self.listOfBrusts)):
self.calculateResults()
plt.figure(figsize=(10,7))
plt.plot(range(self.B),self.TotalMeanHitsPerBrust)
plt.xlabel("Brust length")
plt.ylabel("AVG Number of hits")
plt.title("N="+str(self.N)+" D="+str(self.D)+" B="+str(self.B))
else:
print("must aim and fire first")
#this class inheritets from experiemnts
#creates a list of bursts and stores mean number of hits for each one
#brustList - list of bursts
#BrustMeanNumberOfHits - mean number of hits per group of brusts
class brusts(experiment):
def __init__(self,N,D,B):
experiment.__init__(self,N,D,B)
self.brustList = []
self.BrustMeanNumberOfHits = 0
#function that creates a single length brusts
def createSingleLengthBrusts(self):
if(not len(self.brustList)):
self.brustList = [brust(i,self.D,self.B) for i in range(self.N)]
#function which calculates burst mean number of hits
def calBrusMeanNumberOfHits(self):
if(not self.BrustMeanNumberOfHits):
tmpSum = 0
for j in range(self.N):
self.brustList[j].calInTargetShoots()
tmpSum += self.brustList[j].inTargetShoots
self.BrustMeanNumberOfHits = tmpSum/self.N
#function which prints bursts and thire x1 y1 (common error cordinates)
def printBrustsCor(self):
for j in range(self.N):
print("N: "+str(self.N)+" burstLength: "+str(self.B)+" x1: "+str(self.brustList[j].x1)+" y1: "+str(self.brustList[j].y1))
#function which creates brust common error list in x and y axis
#stores it at BrustCEcorX/Y list
def calBrustsCECor(self):
self.BrustCEcorX = []
self.BrustCEcorY = []
for j in range(self.N):
self.BrustCEcorX.append(self.brustList[j].x1)
self.BrustCEcorY.append(self.brustList[j].y1)
#function which plots single brust common error cordinates
def plotBrustCor(self):
plt.figure(figsize=(10,7))
self.calBrustsCECor()
plt.scatter(self.BrustCEcorX,self.BrustCEcorY,marker='+')
plt.scatter(0,0,s=2000,marker='+',color='blue')
#this class inhiratets from bursts
#x1,y1 - sotres x1,y1 cordiantes of the common eror of the burst
#inTargetShoots - stores shoots in traget counter
class brust(brusts):
def __init__(self,N,D,B):
brusts.__init__(self,N,D,B)
self.x1 = np.random.normal(0,(self.CError * self.D)/self.cons)
self.y1 = np.random.normal(0,(self.CError * self.D)/self.cons)
self.ListOfShoots = []
self.inTargetShoots = 0
#function to fire a brust
#ListOfShoots - stores list of shoots - bullet objects
def fireBrust(self):
if(not len(self.ListOfShoots)):
self.ListOfShoots = [bullet(self.N,self.D,i) for i in range(self.B)]
#function to counts number of bullets hit the target
def calInTargetShoots(self):
if(not self.inTargetShoots):
for k in range(self.B):
if(self.ListOfShoots[k].inTarget):
self.inTargetShoots+=1
#function to calculate the exact cordiantes of each bullet
def calShootsCor(self):
self.ShotsX = []
self.ShotsY = []
for k in range(self.B):
self.ShotsX.append(self.ListOfShoots[k].x2)
self.ShotsY.append(self.ListOfShoots[k].y2)
#function to plot single brust shoots
def plotShots(self):
plt.figure(figsize=(10,7))
plt.scatter(self.x1,self.y1,s=500,marker='+')
self.calShootsCor()
plt.scatter(self.ShotsX,self.ShotsY)
plt.title("Distance = "+str(self.D)+" KM")
plt.scatter(0,0,s=2000,marker='+',color='blue')
#this class inhiratets from burst
#one object created (x2,y2) cordiantes calculates out of brust common error cordinates (x1,y1)
#x2 - x cordiante of the hit
#y2 - y cordiante of the hit
#inTarget - boolean, True if in targer range
class bullet(brust):
def __init__(self,N,D,B):
brust.__init__(self,N,D,B)
self.x2 = np.random.normal(self.x1,(self.REror * self.D)/self.cons)
self.y2 = np.random.normal(self.y1,(self.REror * self.D)/self.cons)
self.inTarget = (self.x2<=self.maxTargetX and self.x2>=self.minTargetX and self.y2<=self.maxTargetY and self.y2>=self.minTargetY)
# Initate Experiments
#exp = experiments(10000,10,10)
#exp.runAllSimulates()
#exp.plotAllSimulates(saveFig=True)
#exp.plotAllSimulates2(saveFig=True)
#exp.plotAllSimulates3(saveFig=True)