pypharm 1.1.0__tar.gz → 1.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pypharm
3
- Version: 1.1.0
3
+ Version: 1.1.2
4
4
  Summary: Module for solving pharmacokinetic problems
5
5
  Home-page: https://github.com/Krash13/PyPharm
6
6
  Author: Krash13
@@ -0,0 +1,493 @@
1
+ import random
2
+ import numpy as np
3
+ from operator import attrgetter
4
+ from math import ceil, cos, sin
5
+
6
+
7
+ class Individual:
8
+
9
+ def __init__(self, x, function):
10
+ self.x = x
11
+ self.f = function(self.x)
12
+ self.ep_n = 0
13
+
14
+ def update_function(self, function):
15
+ self.f = function(self.x)
16
+
17
+ @classmethod
18
+ def crossing(cls, individual1, individual2, p, function, Xmin, Xmax):
19
+ x1 = []
20
+ x2 = []
21
+ for i in range(len(individual1.x)):
22
+ if i % 2:
23
+ x1.append(individual1.x[i])
24
+ x2.append(individual2.x[i])
25
+ else:
26
+ x1.append(individual2.x[i])
27
+ x2.append(individual1.x[i])
28
+ x1[i] += random.uniform(-p * x1[i], p * x1[i])
29
+ x1[i] = x1[i] if x1[i] >= Xmin[i] else Xmin[i]
30
+ x1[i] = x1[i] if x1[i] <= Xmax[i] else Xmax[i]
31
+ x2[i] += random.uniform(-p * x2[i], p * x2[i])
32
+ x2[i] = x2[i] if x2[i] >= Xmin[i] else Xmin[i]
33
+ x2[i] = x2[i] if x2[i] <= Xmax[i] else Xmax[i]
34
+ return [cls(x1, function), cls(x2, function)]
35
+
36
+ @classmethod
37
+ def crossing2(cls, individual1, individual2, p, function, Xmin, Xmax):
38
+ x1 = []
39
+ x2 = []
40
+ random_list = list(range(len(individual1.x)))
41
+ random.shuffle(random_list)
42
+ random_list = random_list[:len(individual1.x) // 2]
43
+ for i in range(len(individual1.x)):
44
+ if i in random_list:
45
+ x1.append(individual1.x[i])
46
+ x2.append(individual2.x[i])
47
+ else:
48
+ x1.append(individual2.x[i])
49
+ x2.append(individual1.x[i])
50
+ x1[i] += random.uniform(-p * x1[i], p * x1[i])
51
+ x1[i] = x1[i] if x1[i] >= Xmin[i] else Xmin[i]
52
+ x1[i] = x1[i] if x1[i] <= Xmax[i] else Xmax[i]
53
+ x2[i] += random.uniform(-p * x2[i], p * x2[i])
54
+ x2[i] = x2[i] if x2[i] >= Xmin[i] else Xmin[i]
55
+ x2[i] = x2[i] if x2[i] <= Xmax[i] else Xmax[i]
56
+ return [cls(x1, function), cls(x2, function)]
57
+
58
+ @classmethod
59
+ def crossing3(cls, individual1, individual2, p, function, Xmin, Xmax):
60
+ x1 = []
61
+ x2 = []
62
+ max_n = len(individual1.x) // 2
63
+ n = random.randint(1, max_n)
64
+ l = []
65
+ for i in range(len(individual1.x) // n):
66
+ l += [j + 2 * i * n for j in range(n) if j + 2 * i * n < len(individual1.x)]
67
+ for i in range(len(individual1.x)):
68
+ if i in l:
69
+ x1.append(individual1.x[i])
70
+ x2.append(individual2.x[i])
71
+ else:
72
+ x1.append(individual2.x[i])
73
+ x2.append(individual1.x[i])
74
+ x1[i] += random.uniform(-p * x1[i], p * x1[i])
75
+ x1[i] = x1[i] if x1[i] >= Xmin[i] else Xmin[i]
76
+ x1[i] = x1[i] if x1[i] <= Xmax[i] else Xmax[i]
77
+ x2[i] += random.uniform(-p * x2[i], p * x2[i])
78
+ x2[i] = x2[i] if x2[i] >= Xmin[i] else Xmin[i]
79
+ x2[i] = x2[i] if x2[i] <= Xmax[i] else Xmax[i]
80
+ return [cls(x1, function), cls(x2, function)]
81
+
82
+ @classmethod
83
+ def crossing4(cls, individual1, individual2, p, function, Xmin, Xmax):
84
+ x1 = []
85
+ x2 = []
86
+ for i in range(len(individual1.x)):
87
+ x1.append((individual1.x[i] + individual2.x[i]) / 2)
88
+ x2.append((individual1.x[i] + individual2.x[i]) / 2)
89
+ x2[i] += random.uniform(-p * x2[i], p * x2[i])
90
+ x2[i] = x2[i] if x2[i] >= Xmin[i] else Xmin[i]
91
+ x2[i] = x2[i] if x2[i] <= Xmax[i] else Xmax[i]
92
+ return [cls(x1, function), cls(x2, function)]
93
+
94
+ @classmethod
95
+ def crossing5(cls, individual1, individual2, p, function, Xmin, Xmax):
96
+ x1 = []
97
+ # x2 = []
98
+ for i in range(len(individual1.x)):
99
+ x1.append((individual1.x[i] + individual2.x[i]) / 2)
100
+ # x2.append((individual1.x[i] + individual2.x[i]) / 2)
101
+ # x2[i] += random.uniform(-p * x2[i], p * x2[i])
102
+ # x2[i] = x2[i] if x2[i] >= Xmin[i] else Xmin[i]
103
+ # x2[i] = x2[i] if x2[i] <= Xmax[i] else Xmax[i]
104
+ return [cls(x1, function)] #, cls(x2, function)]
105
+
106
+ @classmethod
107
+ def crossing6(cls, individual1, individual2, p, function, Xmin, Xmax):
108
+ x1 = []
109
+ k = random.random()
110
+ if k > 0.5:
111
+ x2 = []
112
+ for i in range(len(individual1.x)):
113
+ x1.append((individual1.x[i] + individual2.x[i]) / 2)
114
+ if k > 0.5:
115
+ x2.append((individual1.x[i] + individual2.x[i]) / 2)
116
+ x2[i] += random.uniform(-p * x2[i], p * x2[i])
117
+ x2[i] = x2[i] if x2[i] >= Xmin[i] else Xmin[i]
118
+ x2[i] = x2[i] if x2[i] <= Xmax[i] else Xmax[i]
119
+ if k > 0.5:
120
+ return [cls(x1, function), cls(x2, function)]
121
+ return [cls(x1, function)]
122
+
123
+ @classmethod
124
+ def crossing7(cls, individual1, individual2, p, function, Xmin, Xmax):
125
+ k = random.random()
126
+ if k <= 1 / 3:
127
+ return Individual.crossing4(individual1, individual2, p, function, Xmin, Xmax)
128
+ elif k <= 2 / 3:
129
+ return Individual.crossing8(individual1, individual2, p, function, Xmin, Xmax)
130
+ else:
131
+ return Individual.crossing6(individual1, individual2, p, function, Xmin, Xmax)
132
+
133
+ @classmethod
134
+ def crossing8(cls, individual1, individual2, p, function, Xmin, Xmax):
135
+ new_x = []
136
+ alpha = 0.5
137
+ for i in range(len(individual1.x)):
138
+ c_min = min(individual1.x[i], individual2.x[i])
139
+ c_max = max(individual1.x[i], individual2.x[i])
140
+ I = c_max - c_min
141
+ new_x.append(random.uniform(c_min - I * alpha, c_max + I * alpha))
142
+ new_x = np.clip(new_x, Xmin, Xmax)
143
+ return [cls(new_x, function)]
144
+
145
+
146
+ @classmethod
147
+ def crossing9(cls, individual1, individual2, p, function, Xmin, Xmax):
148
+ new_x = []
149
+ alpha = 0.5
150
+ for i in range(len(individual1.x)):
151
+ c_min = min(individual1.x[i], individual2.x[i])
152
+ c_max = max(individual1.x[i], individual2.x[i])
153
+ I = c_max - c_min
154
+ new_x.append(random.uniform(c_min - I * alpha, c_max + I * alpha))
155
+ new_x = np.clip(new_x, Xmin, Xmax)
156
+ if random.random() <= 0.5:
157
+ for i in range(len(individual1.x)):
158
+ new_x[i] += random.uniform(-p * new_x[i], p * new_x[i])
159
+ new_x = np.clip(new_x, Xmin, Xmax)
160
+ return [cls(new_x, function)]
161
+
162
+ @classmethod
163
+ def crossing10(cls, individual1, individual2, p, function, Xmin, Xmax, p2):
164
+ k = random.random()
165
+ if k <= 1 / 3:
166
+ return Individual.crossing9(individual1, individual2, p, function, Xmin, Xmax, p2)
167
+ else:
168
+ return Individual.crossing8(individual1, individual2, p, function, Xmin, Xmax)
169
+
170
+ @classmethod
171
+ def crossing11(cls, individual1, individual2, p, function, Xmin, Xmax):
172
+ new_x = []
173
+ alpha = p
174
+ for i in range(len(individual1.x)):
175
+ c_min = min(individual1.x[i], individual2.x[i])
176
+ c_max = max(individual1.x[i], individual2.x[i])
177
+ I = c_max - c_min
178
+ new_x.append(random.uniform(c_min - I * alpha, c_max + I * alpha))
179
+ new_x = np.clip(new_x, Xmin, Xmax)
180
+ return [cls(new_x, function)]
181
+
182
+ def mutation(self, Xmin, Xmax, function, pmax):
183
+ self.ep_n += 1
184
+ for i in range(len(self.x)):
185
+ self.x[i] += pmax * random.uniform(-self.x[i], self.x[i]) / self.ep_n
186
+ self.x[i] = self.x[i] if self.x[i] >= Xmin[i] else Xmin[i]
187
+ self.x[i] = self.x[i] if self.x[i] <= Xmax[i] else Xmax[i]
188
+ self.update_function(function)
189
+
190
+
191
+ class Country:
192
+
193
+ def __init__(self, Xmin, Xmax, N, function):
194
+ x_min = []
195
+ x_max = []
196
+ for i in range(len(Xmin)):
197
+ x_min.append(random.uniform(Xmin[i], Xmax[i]))
198
+ x_max.append(random.uniform(x_min[i], Xmax[i]))
199
+ self.population = []
200
+ for i in range(N):
201
+ x = []
202
+ for j in range(len(Xmin)):
203
+ x.append(random.uniform(x_min[j], x_max[j]))
204
+ self.population.append(Individual(x, function))
205
+ self.sort_population()
206
+ self.action = None
207
+ self.enemy = None
208
+ self.ally = None
209
+
210
+ @property
211
+ def best_function(self):
212
+ return self.population[0].f
213
+
214
+ @property
215
+ def avg_function(self):
216
+ return sum([individual.f for individual in self.population]) / len(self.population)
217
+
218
+ def update_population(self, function):
219
+ for individual in self.population:
220
+ individual.update_function(function)
221
+
222
+ def sort_population(self):
223
+ self.population.sort(key=attrgetter('f'))
224
+
225
+ def reproduction(self, n_min, n_max, p_min, p_max, f_min, f_max, ti, t_max, function, Xmin, Xmax):
226
+ n = ceil((n_max - n_min) * (f_max - self.avg_function) / (f_max - f_min) + n_min)
227
+ n = np.clip(n, n_min, n_max)
228
+ p = (p_max - p_min) * (1 - ti / t_max) * (self.avg_function - f_min) / (f_max - f_min) + p_min
229
+ p = np.clip(p, p_min, p_max)
230
+ # p2 = (1 - ti / t_max) * (self.avg_function - f_min) / (f_max - f_min)
231
+ new_individuals = []
232
+
233
+ for i in range(n):
234
+ if len(self.population) == 2 and self.population[0] == self.population[1]:
235
+ new_individuals.extend(Individual.crossing11(self.population[0], self.population[1], p, function, Xmin, Xmax))
236
+ continue
237
+ k1 = random.randint(0, len(self.population) - 1)
238
+ individual1 = self.population[k1]
239
+ k2 = k1
240
+ while k2 == k1:
241
+ k2 = random.randint(0, len(self.population) - 1)
242
+ individual2 = self.population[k2]
243
+ new_individuals.extend(Individual.crossing11(individual1, individual2, p, function, Xmin, Xmax))
244
+ self.population.extend(new_individuals)
245
+ self.sort_population()
246
+
247
+ def extinction(self, m_min, m_max, f_min, f_max):
248
+ m = int((m_max - m_min) * (self.avg_function - f_min) / (f_max - f_min) + m_min)
249
+ m = m if m <= m_max else m_max
250
+ m = m if m >= m_min else m_min
251
+ self.population = self.population[:-m]
252
+
253
+ def select_action(self, countries):
254
+ self.action = random.randint(0, 3)
255
+ if self.action == 1:
256
+ ally_list = [country for country in countries if country.action is None and country != self]
257
+ if ally_list:
258
+ self.ally = ally_list.pop(random.randint(0, len(ally_list) - 1))
259
+ self.ally.action = 1
260
+ self.ally.ally = self
261
+ else:
262
+ self.action = random.choice([0, 3])
263
+ if self.action == 2:
264
+ enemy_list = [country for country in countries if country.action is None and country != self]
265
+ if enemy_list:
266
+ self.enemy = enemy_list.pop(random.randint(0, len(enemy_list) - 1))
267
+ self.enemy.action = 2
268
+ self.enemy.enemy = self
269
+ else:
270
+ self.action = random.choice([0, 3])
271
+
272
+ def epedemic(self, elite, dead, function, Xmin, Xmax, p_max):
273
+ n_elite = ceil(elite * len(self.population))
274
+ n_dead = ceil(dead * len(self.population))
275
+ self.population = self.population[:-n_dead]
276
+ for individual in self.population[n_elite:]:
277
+ individual.mutation(Xmin, Xmax, function, p_max)
278
+ self.sort_population()
279
+ self.action = None
280
+
281
+ # def sabotage(self, n_copy):
282
+ # for i in range(n_copy):
283
+ # self.enemy.population.append(copy.copy(self.population[0]))
284
+ # self.action = None
285
+ # self.enemy = None
286
+
287
+ def motion(self, function, Xmin, Xmax):
288
+ x_best = self.population[0].x
289
+ for i in range(1, len(self.population)):
290
+ for j in range(len(x_best)):
291
+ self.population[i].x[j] += random.uniform(0, 2) * (x_best[j] - self.population[i].x[j])
292
+ self.population[i].x[j] = self.population[i].x[j] if self.population[i].x[j] >= Xmin[j] else Xmin[j]
293
+ self.population[i].x[j] = self.population[i].x[j] if self.population[i].x[j] <= Xmax[j] else Xmax[j]
294
+ self.update_population(function)
295
+ self.sort_population()
296
+ self.action = None
297
+
298
+ @staticmethod
299
+ def trade(country1, country2, k):
300
+ trade_list1 = []
301
+ trade_list2 = []
302
+ if len(country1.population) <= k or len(country2.population) <= k:
303
+ k = min(len(country1.population), len(country2.population)) // 2
304
+ for i in range(k):
305
+ trade_list1.append(country1.population.pop(random.randint(0, len(country1.population) - 1)))
306
+ trade_list2.append(country2.population.pop(random.randint(0, len(country2.population) - 1)))
307
+ country1.population.extend(trade_list2)
308
+ country2.population.extend(trade_list1)
309
+ country1.sort_population()
310
+ country2.sort_population()
311
+ country1.action = None
312
+ country2.action = None
313
+ country1.ally = None
314
+ country2.ally = None
315
+
316
+ @staticmethod
317
+ def war(country1, country2, l):
318
+ war_list1 = []
319
+ war_list2 = []
320
+ if len(country1.population) <= l or len(country2.population) <= l:
321
+ l = min(len(country1.population), len(country2.population))
322
+ for i in range(l):
323
+ war_list1.append(country1.population.pop(random.randint(0, len(country1.population) - 1)))
324
+ war_list2.append(country2.population.pop(random.randint(0, len(country2.population) - 1)))
325
+ wins1 = 0
326
+ wins2 = 0
327
+ for i in range(l-1, -1, -1):
328
+ if war_list1[i].f < war_list2[i].f:
329
+ war_list2.pop(i)
330
+ wins1 += 1
331
+ elif war_list1[i].f > war_list2[i].f:
332
+ war_list1.pop(i)
333
+ wins2 += 1
334
+ if wins1 > wins2:
335
+ country1.population.extend(war_list1)
336
+ country1.population.extend(war_list2)
337
+ elif wins2 > wins1:
338
+ country2.population.extend(war_list1)
339
+ country2.population.extend(war_list2)
340
+ else:
341
+ country1.population.extend(war_list1)
342
+ country2.population.extend(war_list2)
343
+ country1.sort_population()
344
+ country2.sort_population()
345
+ country1.action = None
346
+ country2.action = None
347
+ country1.enemy = None
348
+ country2.enemy = None
349
+
350
+
351
+ class CountriesAlgorithm:
352
+
353
+ def __init__(self, f, Xmin, Xmax, M, N, n, p, m, k, l, ep, tmax, printing=False):
354
+ self.f = f
355
+ self.Xmin = Xmin
356
+ self.Xmax = Xmax
357
+ self.n = n
358
+ self.p = p
359
+ self.m = m
360
+ self.k = k
361
+ self.l = l
362
+ self.ep = ep
363
+ self.tmax = tmax
364
+ self.countries = []
365
+ self.printing = printing
366
+ for i in range(M):
367
+ self.countries.append(Country(self.Xmin, self.Xmax, N, self.f))
368
+
369
+ def start(self):
370
+ ti = 0
371
+ motion = 0
372
+ trade = 0
373
+ war = 0
374
+ epedemic = 0
375
+ while ti <= self.tmax:
376
+ ti += 1
377
+ for country in self.countries:
378
+ if country.action is None:
379
+ country.select_action(self.countries)
380
+ for country in self.countries:
381
+ if country.action == 0:
382
+ motion += 1
383
+ country.motion(
384
+ function=self.f,
385
+ Xmin=self.Xmin,
386
+ Xmax=self.Xmax
387
+ )
388
+ elif country.action == 1:
389
+ trade += 1
390
+ Country.trade(
391
+ country1=country,
392
+ country2=country.ally,
393
+ k=self.k
394
+ )
395
+ elif country.action == 2:
396
+ war += 1
397
+ Country.war(
398
+ country1=country,
399
+ country2=country.enemy,
400
+ l=self.l
401
+ )
402
+ elif country.action == 3:
403
+ epedemic += 1
404
+ country.epedemic(
405
+ elite=self.ep[0],
406
+ dead=self.ep[1],
407
+ Xmin=self.Xmin,
408
+ Xmax=self.Xmax,
409
+ function=self.f,
410
+ p_max=self.p[1],
411
+ )
412
+ self.countries = [country for country in self.countries if country.population]
413
+ self.countries = sorted(self.countries, key=attrgetter('avg_function'))
414
+ if not self.countries:
415
+ break
416
+ f_min = self.countries[0].avg_function
417
+ f_max = self.countries[-1].avg_function
418
+ if f_min == f_max:
419
+ self.countries = sorted(self.countries, key=attrgetter('best_function'))
420
+ result = self.countries[0].population[0]
421
+ break
422
+ e_individuals = []
423
+ for country in self.countries:
424
+ if len(country.population) == 1:
425
+ e_individuals.append(country.population[0])
426
+ continue
427
+ if country.population:
428
+ country.reproduction(
429
+ n_min=self.n[0],
430
+ n_max=self.n[1],
431
+ p_min=self.p[0],
432
+ p_max=self.p[1],
433
+ f_min=f_min,
434
+ f_max=f_max,
435
+ ti=ti,
436
+ t_max=self.tmax,
437
+ function=self.f,
438
+ Xmin=self.Xmin,
439
+ Xmax=self.Xmax
440
+ )
441
+ country.extinction(
442
+ m_min=self.m[0],
443
+ m_max=self.m[1],
444
+ f_min=f_min,
445
+ f_max=f_max
446
+ )
447
+ self.countries = [country for country in self.countries if country.population]
448
+ for individual in e_individuals:
449
+ random_country = self.countries[random.randint(0, len(self.countries) - 1)]
450
+ random_country.population.append(individual)
451
+ random_country.sort_population()
452
+ self.countries = sorted(self.countries, key=attrgetter('best_function'))
453
+ if not self.countries:
454
+ break
455
+ result = self.countries[0].population[0]
456
+
457
+ if self.printing:
458
+ print(f"{ti}) Лучшее решение: {result.x} - {result.f}, Стран осталось: {len(self.countries)}, Движение/Обмен/Войны/Эпидемии: {motion}/{trade}/{war}/{epedemic}")
459
+ print(f"Общее количество особей: {sum([len(country.population) for country in self.countries])}")
460
+ return (result.x, result.f, False, ti)
461
+
462
+
463
+
464
+ # def func(x):
465
+ # s = 0
466
+ # for i in range(len(x) - 1):
467
+ # s += -x[i] * np.sin(abs(x[i] - x[i+1] - 47) ** 0.5) - (x[i+1] + 47) * np.sin(abs(x[i+1] + x[i] / 2 + 47) ** 0.5)
468
+ # return s
469
+ #
470
+ # k = 0
471
+ # for i in range(100):
472
+ # CA = CountriesAlgorithm(
473
+ # f=func,
474
+ # Xmin=[-512 for i in range(3)],
475
+ # Xmax=[512 for i in range(3)],
476
+ # M=100,
477
+ # N=15,
478
+ # n=[1, 10],
479
+ # p=[0.00001, 2.5],
480
+ # m=[1, 8],
481
+ # k=8,
482
+ # l=3,
483
+ # ep=[0.2, 0.4],
484
+ # tmax=300,
485
+ # printing=False,
486
+ # teoretic_y=-1888.3213909
487
+ # )
488
+ # r = CA.start()
489
+ # print(i, r[2], r[0], r[1])
490
+ # if r[2]:
491
+ # k += 1
492
+ #
493
+ # print(k/100)
@@ -1,7 +1,7 @@
1
1
  import numpy as np
2
2
  from scipy.integrate import solve_ivp
3
3
  from scipy.optimize import minimize
4
- from country_optimization import CountriesAlgorithm
4
+ from .country_optimization import CountriesAlgorithm
5
5
 
6
6
 
7
7
  class BaseCompartmentModel:
@@ -100,6 +100,7 @@ class BaseCompartmentModel:
100
100
  **kwargs
101
101
  )
102
102
  CA.start()
103
+ x = CA.countries[0].population[0].x
103
104
  else:
104
105
  res = minimize(
105
106
  fun=f,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pypharm
3
- Version: 1.1.0
3
+ Version: 1.1.2
4
4
  Summary: Module for solving pharmacokinetic problems
5
5
  Home-page: https://github.com/Krash13/PyPharm
6
6
  Author: Krash13
@@ -2,6 +2,7 @@ README.md
2
2
  setup.cfg
3
3
  setup.py
4
4
  PyPharm/__init__.py
5
+ PyPharm/country_optimization.py
5
6
  PyPharm/models.py
6
7
  pypharm.egg-info/PKG-INFO
7
8
  pypharm.egg-info/SOURCES.txt
@@ -6,7 +6,7 @@ def readme():
6
6
 
7
7
  setup(
8
8
  name='pypharm',
9
- version='1.1.0',
9
+ version='1.1.2',
10
10
  author='Krash13',
11
11
  author_email='krasheninnikov.r.s@muctr.ru',
12
12
  description='Module for solving pharmacokinetic problems',
File without changes
File without changes
File without changes