pypharm 1.3.2__py3-none-any.whl → 1.3.5__py3-none-any.whl

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.
@@ -2,7 +2,6 @@ import random
2
2
  import numpy as np
3
3
  from operator import attrgetter
4
4
  from math import ceil, cos, sin
5
- from multiprocessing import shared_memory
6
5
 
7
6
 
8
7
  class Individual:
@@ -469,35 +468,3 @@ class CountriesAlgorithm:
469
468
  self.memory_list[-1] = float(result.f)
470
469
  return (result.x, result.f, False, ti)
471
470
 
472
-
473
-
474
- # def func(x):
475
- # s = 0
476
- # for i in range(len(x) - 1):
477
- # 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)
478
- # return s
479
- #
480
- # k = 0
481
- # for i in range(100):
482
- # CA = CountriesAlgorithm(
483
- # f=func,
484
- # Xmin=[-512 for i in range(3)],
485
- # Xmax=[512 for i in range(3)],
486
- # M=100,
487
- # N=15,
488
- # n=[1, 10],
489
- # p=[0.00001, 2.5],
490
- # m=[1, 8],
491
- # k=8,
492
- # l=3,
493
- # ep=[0.2, 0.4],
494
- # tmax=300,
495
- # printing=False,
496
- # teoretic_y=-1888.3213909
497
- # )
498
- # r = CA.start()
499
- # print(i, r[2], r[0], r[1])
500
- # if r[2]:
501
- # k += 1
502
- #
503
- # print(k/100)
@@ -0,0 +1,426 @@
1
+ import random
2
+ import numpy as np
3
+ import copy
4
+ from operator import attrgetter
5
+ from math import ceil, cos, sin
6
+ import graycode
7
+
8
+ def rand_str():
9
+ s = 'qwertyuiopasdfghjklzxcvbnm'
10
+ k = np.random.choice(len(s), 8, replace=False)
11
+ res = ''
12
+ for ki in k:
13
+ res += s[ki]
14
+ return res
15
+
16
+ def check_population(country):
17
+ return bool(country.population.size)
18
+
19
+ vector_check_population = np.vectorize(check_population, signature='()->()')
20
+
21
+ class Individual:
22
+
23
+ def __init__(self, gray_code, x_min, x_max, genes, function):
24
+
25
+ self.x_min = x_min
26
+ self.x_max = x_max
27
+ self.genes = genes
28
+ self.function = function
29
+ self.steps = (self.x_max - self.x_min) / (2 ** (self.genes) - 1)
30
+ self.gray_code = gray_code
31
+ self.f = self.function(self.real_x)
32
+ self.ep_n = 0
33
+
34
+ @property
35
+ def real_x(self):
36
+ decimal_x = []
37
+ gray_code = copy.deepcopy(self.gray_code)
38
+ for g in self.genes:
39
+ decimal_x.append(graycode.gray_code_to_tc(int(gray_code[:g], base=2)))
40
+ gray_code = gray_code[g:]
41
+ return self.x_min + self.steps * np.array(decimal_x)
42
+
43
+ @property
44
+ def decimal_x(self):
45
+ return (self.real_x - self.x_min) / self.steps
46
+
47
+ @classmethod
48
+ def generate_from_decimal(cls, decimal, x_min, x_max, genes, function):
49
+ gray_code = ''
50
+ decimal = np.clip(decimal, np.zeros(decimal.size), 2 ** (genes) - 1)
51
+ for i in range(len(decimal)):
52
+ s = '{:0' + str(genes[i]) + 'b}'
53
+ gray_code += s.format(graycode.tc_to_gray_code(int(decimal[i])))
54
+
55
+ return cls(gray_code, x_min, x_max, genes, function)
56
+
57
+ def mutation(self, max_mutation=1):
58
+ n = max(0, max_mutation - self.ep_n)
59
+ if n:
60
+ gray_code = copy.deepcopy(self.gray_code)
61
+ k = np.random.choice(len(gray_code), n, replace=False)
62
+ for ki in k:
63
+ b = bool(int(gray_code[ki]))
64
+ b = not b
65
+ b = str(int(b))
66
+ gray_code = gray_code[:ki] + b + gray_code[ki+1:]
67
+ return Individual(gray_code, self.x_min, self.x_max, self.genes, self.function)
68
+ else:
69
+ return self
70
+
71
+ @classmethod
72
+ def crossover(cls, individual1, individual2):
73
+ k = np.random.randint(1, len(individual1.gray_code) - 1, 2)
74
+ while k[0] == k[1]:
75
+ k = np.random.randint(1, len(individual1.gray_code) - 1, 2)
76
+ k = np.sort(k)
77
+ new_gray1 = individual1.gray_code[:k[0]] + individual2.gray_code[k[0]:k[1]] + individual1.gray_code[k[1]:]
78
+ new_gray2 = individual2.gray_code[:k[0]] + individual1.gray_code[k[0]:k[1]] + individual2.gray_code[k[1]:]
79
+ return [
80
+ cls(new_gray1, individual1.x_min, individual1.x_max, individual1.genes, individual1.function),
81
+ cls(new_gray2, individual1.x_min, individual1.x_max, individual1.genes, individual1.function),
82
+ ]
83
+
84
+ def __lt__(self, other):
85
+ return self.f < other.f
86
+
87
+ def __le__(self, other):
88
+ return self.f <= other.f
89
+
90
+ def __gt__(self, other):
91
+ return self.f > other.f
92
+
93
+ def __ge__(self, other):
94
+ return self.f >= other.f
95
+
96
+
97
+ class Country:
98
+
99
+ def __init__(self, N, x_min, x_max, genes, function):
100
+ self.f = function
101
+ self.N = N
102
+ self.x_min = np.array(x_min)
103
+ self.x_max = np.array(x_max)
104
+ self.genes = np.array(genes)
105
+ self.name = rand_str()
106
+
107
+
108
+ local_xmin = np.random.randint(np.zeros(self.genes.size), 2 ** self.genes - 1)
109
+ local_xmax = np.random.randint(local_xmin, 2 ** self.genes)
110
+
111
+ self.rand_n_individual = np.vectorize(lambda x: x * self.random_individual(local_xmin, local_xmax), signature='()->(n)')
112
+ self.generate_population = np.vectorize(lambda decimal: Individual.generate_from_decimal(
113
+ decimal, self.x_min, self.x_max, self.genes, self.f), signature='(n)->()')
114
+
115
+ x = self.rand_n_individual(np.ones(self.N))
116
+ self.population = self.generate_population(x)
117
+
118
+
119
+ self.sort_population()
120
+ self.action = None
121
+ self.enemy = None
122
+ self.ally = None
123
+
124
+ def random_individual(self, x_min, x_max):
125
+ return np.random.randint(x_min, x_max)
126
+
127
+ @property
128
+ def best_function(self):
129
+ return self.population[0].f
130
+
131
+ def roulette_function(self, f_min, f_max):
132
+ return (f_max - self.population[0].f) / (f_max - f_min)
133
+
134
+ @property
135
+ def avg_function(self):
136
+ return sum([individual.f for individual in self.population]) / self.population.size
137
+
138
+ def sort_population(self):
139
+ self.population.sort()
140
+
141
+ def reproduction(self, n_min, n_max, f_min, f_max):
142
+ n = ceil((n_max - n_min) * (f_max - self.avg_function) / (f_max - f_min) + n_min)
143
+ n = np.clip(n, n_min, n_max)
144
+ # p2 = (1 - ti / t_max) * (self.avg_function - f_min) / (f_max - f_min)
145
+ new_individuals = []
146
+
147
+ for i in range(n):
148
+ if len(self.population) == 2 and self.population[0] == self.population[1]:
149
+ new_individuals.extend(Individual.crossover(self.population[0], self.population[1],
150
+ self.x_min, self.x_max, self.genes, self.f))
151
+ continue
152
+ k1 = random.randint(0, len(self.population) - 1)
153
+ individual1 = self.population[k1]
154
+ k2 = k1
155
+ while k2 == k1:
156
+ k2 = random.randint(0, len(self.population) - 1)
157
+ individual2 = self.population[k2]
158
+ new_individuals += Individual.crossover(individual1, individual2)
159
+ self.population = np.append(self.population, np.array(new_individuals))
160
+ self.sort_population()
161
+
162
+ def extinction(self, m_min, m_max, f_min, f_max):
163
+ m = int((m_max - m_min) * (self.avg_function - f_min) / (f_max - f_min) + m_min)
164
+ m = np.clip(m, m_min, m_max)
165
+ self.population = self.population[:-m]
166
+
167
+ def extinction1(self, n):
168
+ if self.population.size < n:
169
+ return n - self.population.size
170
+ self.population = self.population[:n]
171
+ return 0
172
+
173
+ def select_action(self, countries):
174
+ self.action = random.randint(0, 3)
175
+ if self.action == 1:
176
+ ally_list = [country for country in countries if country.action is None and country != self]
177
+ if ally_list:
178
+ self.ally = ally_list.pop(random.randint(0, len(ally_list) - 1))
179
+ self.ally.action = 1
180
+ self.ally.ally = self
181
+ else:
182
+ self.action = random.choice([0, 3])
183
+ if self.action == 2:
184
+ enemy_list = [country for country in countries if country.action is None and country != self]
185
+ if enemy_list:
186
+ self.enemy = enemy_list.pop(random.randint(0, len(enemy_list) - 1))
187
+ self.enemy.action = 2
188
+ self.enemy.enemy = self
189
+ else:
190
+ self.action = random.choice([0, 3])
191
+
192
+ def epedemic(self, elite, dead, max_mutation):
193
+ if max_mutation < 1:
194
+ max_mutation = 1
195
+ n_elite = ceil(elite * len(self.population))
196
+ n_dead = ceil(dead * len(self.population))
197
+ self.population = self.population[:-n_dead]
198
+ for i in range(n_elite, self.population.size):
199
+ self.population[i] = self.population[i].mutation(max_mutation)
200
+ self.sort_population()
201
+ self.action = None
202
+
203
+ # def sabotage(self, n_copy):
204
+ # for i in range(n_copy):
205
+ # self.enemy.population.append(copy.copy(self.population[0]))
206
+ # self.action = None
207
+ # self.enemy = None
208
+
209
+ def motion(self):
210
+ x_best = self.population[0].decimal_x
211
+ for i in range(1, len(self.population)):
212
+ self.population[i] = Individual.generate_from_decimal(
213
+ self.population[i].decimal_x + np.int64(random.uniform(0, 2) * (x_best - self.population[i].decimal_x)), self.x_min, self.x_max, self.genes, self.f
214
+ )
215
+ self.sort_population()
216
+ self.action = None
217
+
218
+ @staticmethod
219
+ def trade(country1, country2, k):
220
+ if country1.population.size <= k or country2.population.size <= k:
221
+ k = min(country1.population.size, country2.population.size) // 2
222
+ indexes1 = np.random.choice(country1.population.size, k, replace=False)
223
+ indexes2 = np.random.choice(country2.population.size, k, replace=False)
224
+ country2.population = np.concatenate([country2.population, country1.population[indexes1]])
225
+ country1.population = np.concatenate([country1.population, country2.population[indexes2]])
226
+ country1.population = np.delete(country1.population, indexes1)
227
+ country2.population = np.delete(country2.population, indexes2)
228
+ country1.sort_population()
229
+ country2.sort_population()
230
+ country1.action = None
231
+ country2.action = None
232
+ country1.ally = None
233
+ country2.ally = None
234
+
235
+ @staticmethod
236
+ def war(country1, country2, l):
237
+ if country1.population.size <= l or country2.population.size <= l:
238
+ l = min(country1.population.size, country2.population.size)
239
+ indexes1 = np.random.choice(country1.population.size, l, replace=False)
240
+ indexes2 = np.random.choice(country2.population.size, l, replace=False)
241
+ war_list1 = country1.population[indexes1]
242
+ war_list2 = country2.population[indexes2]
243
+ country1.population = np.delete(country1.population, indexes1)
244
+ country2.population = np.delete(country2.population, indexes2)
245
+ wins1 = np.where(war_list1 > war_list2)
246
+ wins2 = np.where(war_list2 > war_list2)
247
+ if wins1[0].size > wins2[0].size:
248
+ np.concatenate([country1.population, war_list1])
249
+ np.concatenate([country1.population, war_list2])
250
+ elif wins2[0].size > wins1[0].size:
251
+ np.concatenate([country2.population, war_list1])
252
+ np.concatenate([country2.population, war_list2])
253
+ else:
254
+ np.concatenate([country1.population, war_list1])
255
+ np.concatenate([country2.population, war_list2])
256
+ country1.sort_population()
257
+ country2.sort_population()
258
+ country1.action = None
259
+ country2.action = None
260
+ country1.enemy = None
261
+ country2.enemy = None
262
+
263
+
264
+ class CountriesAlgorithm:
265
+
266
+ def __init__(self, f, Xmin, Xmax, genes, M, N, n, m, k, l, ep, max_mutation, tmax, printing=False, memory_list=None):
267
+ self.f = f
268
+ self.Xmin = Xmin
269
+ self.Xmax = Xmax
270
+ self.n = n
271
+ self.genes = genes
272
+ self.m = m
273
+ self.k = k
274
+ self.M = M
275
+ self.N = N
276
+ self.l = l
277
+ self.ep = ep
278
+ self.max_mutation = max_mutation
279
+ self.tmax = tmax
280
+ self.countries = []
281
+ self.printing = printing
282
+ self.memory_list = memory_list
283
+ for i in range(M):
284
+ self.countries.append(Country(N, self.Xmin, self.Xmax, self.genes, self.f))
285
+
286
+ def start(self):
287
+ ti = 0
288
+ motion = 0
289
+ trade = 0
290
+ war = 0
291
+ epedemic = 0
292
+ if self.memory_list is not None:
293
+ self.memory_list[0] = False
294
+ while ti <= self.tmax:
295
+ ti += 1
296
+ for country in self.countries:
297
+ if country.action is None:
298
+ country.select_action(self.countries)
299
+ for country in self.countries:
300
+ if country.action == 0:
301
+ motion += 1
302
+ country.motion( )
303
+ elif country.action == 1:
304
+ trade += 1
305
+ Country.trade(
306
+ country1=country,
307
+ country2=country.ally,
308
+ k=self.k
309
+ )
310
+ elif country.action == 2:
311
+ war += 1
312
+ Country.war(
313
+ country1=country,
314
+ country2=country.enemy,
315
+ l=self.l
316
+ )
317
+ elif country.action == 3:
318
+ epedemic += 1
319
+ country.epedemic(
320
+ elite=self.ep[0],
321
+ dead=self.ep[1],
322
+ max_mutation=int((1 - ti / self.tmax) * self.max_mutation),
323
+ )
324
+ indexes = np.where(vector_check_population(self.countries) == True)
325
+ self.countries = [self.countries[i] for i in indexes[0]]
326
+
327
+ self.countries = sorted(self.countries, key=attrgetter('avg_function'))
328
+ if not self.countries:
329
+ break
330
+ f_min = self.countries[0].avg_function
331
+ f_max = self.countries[-1].avg_function
332
+ if f_min == f_max:
333
+ self.countries = sorted(self.countries, key=attrgetter('best_function'))
334
+ result = self.countries[0].population[0]
335
+ break
336
+ e_individuals = []
337
+ for country in self.countries:
338
+ if len(country.population) == 1:
339
+ e_individuals.append(country.population[0])
340
+ continue
341
+ if country.population.size:
342
+ country.reproduction(
343
+ n_min=self.n[0],
344
+ n_max=self.n[1],
345
+ f_min=f_min,
346
+ f_max=f_max
347
+ )
348
+ # country.extinction(
349
+ # m_min=self.m[0],
350
+ # m_max=self.m[1],
351
+ # f_min=f_min,
352
+ # f_max=f_max
353
+ # )
354
+ self.countries = sorted(self.countries, key=attrgetter('best_function'))
355
+ f_min = self.countries[0].best_function
356
+ f_max = self.countries[-1].best_function
357
+ s = sum(country.roulette_function(f_min, f_max) for country in self.countries if len(country.population) > 1)
358
+ self.countries.reverse()
359
+ for country in self.countries:
360
+ plus = 0
361
+ if len(country.population) >= 1:
362
+ res = country.extinction1(
363
+ max(self.N // 2, ceil(country.roulette_function(f_min, f_max) / s * self.N * self.M)) + plus
364
+ )
365
+ if res:
366
+ plus += res
367
+ else:
368
+ plus = 0
369
+
370
+ indexes = np.where(vector_check_population(self.countries) == True)
371
+ self.countries = [self.countries[i] for i in indexes[0]]
372
+
373
+ for individual in e_individuals:
374
+ random_country = self.countries[random.randint(0, len(self.countries) - 1)]
375
+ np.append(random_country.population, np.array([individual]))
376
+ random_country.sort_population()
377
+ self.countries = sorted(self.countries, key=attrgetter('best_function'))
378
+ if not self.countries:
379
+ break
380
+ result = self.countries[0].population[0]
381
+
382
+ if self.printing:
383
+ print(f"{ti}) Лучшее решение: {result.real_x} - {result.f}, Стран осталось: {len(self.countries)}, Движение/Обмен/Войны/Эпидемии: {motion}/{trade}/{war}/{epedemic}")
384
+ print(f"Общее количество особей: {sum([len(country.population) for country in self.countries])}")
385
+ print("++++++++++++++++++++++++++++++++++++++++++++++++++")
386
+ for i, country in enumerate(self.countries):
387
+ print(f'{i + 1})', country.name, len(country.population), country.best_function, country.avg_function)
388
+ print("++++++++++++++++++++++++++++++++++++++++++++++++++")
389
+
390
+ if self.memory_list is not None:
391
+ self.memory_list[0] = ti
392
+ for i in range(len(result.real_x)):
393
+ self.memory_list[i + 1] = float(result.real_x[i])
394
+ self.memory_list[-1] = float(result.f)
395
+ return (result.real_x, result.f, False, ti)
396
+
397
+
398
+
399
+ # def f(x):
400
+ # return sum([(xi ** 4 - 16 * xi ** 2 + 5 *xi) / 2 for xi in x])
401
+ # #
402
+ # # k = 0
403
+ # # for i in range(100):
404
+ # CA = CountriesAlgorithm(
405
+ # f=f,
406
+ # Xmin=[-5.12 for i in range(3)],
407
+ # Xmax=[5.12 for i in range(3)],
408
+ # genes=[16 for i in range(3)],
409
+ # M=20,
410
+ # N=15,
411
+ # n=[1, 10],
412
+ # m=[3, 8],
413
+ # k=8,
414
+ # l=3,
415
+ # ep=[0.2, 0.4],
416
+ # max_mutation=16,
417
+ # tmax=300,
418
+ # printing=True,
419
+ # )
420
+ # r = CA.start()
421
+
422
+ # print(i, r[2], r[0], r[1])
423
+ # if r[2]:
424
+ # k += 1
425
+ #
426
+ # print(k/100)
@@ -0,0 +1,130 @@
1
+ import graycode
2
+ import numpy as np
3
+ import copy
4
+
5
+ class Individual:
6
+
7
+ x_min = None
8
+ x_max = None
9
+ genes = None
10
+ function = None
11
+ gray_code = None
12
+ f = None
13
+
14
+ def __init__(self, gray_code, x_min, x_max, genes, function, mutation_chance=None, max_mutation=1):
15
+
16
+ self.x_min = x_min
17
+ self.x_max = x_max
18
+ self.genes = genes
19
+ self.function = function
20
+ self.steps = (self.x_max - self.x_min) / (2 ** (self.genes) - 1)
21
+ self.gray_code = gray_code
22
+ if mutation_chance is not None and np.random.random() < mutation_chance:
23
+ self.mutation(max_mutation)
24
+ self.f = self.function(self.real_x)
25
+
26
+ @property
27
+ def real_x(self):
28
+ decimal_x = []
29
+ gray_code = copy.deepcopy(self.gray_code)
30
+ for g in self.genes:
31
+ decimal_x.append(graycode.gray_code_to_tc(int(gray_code[:g], base=2)))
32
+ gray_code = gray_code[g:]
33
+ return self.x_min + self.steps * np.array(decimal_x)
34
+
35
+ @property
36
+ def decimal_x(self):
37
+ return (self.real_x - self.x_min) / self.steps
38
+
39
+ @classmethod
40
+ def generate_from_decimal(cls, decimal, x_min, x_max, genes, function):
41
+ gray_code = ''
42
+ decimal = np.clip(decimal, np.zeros(decimal.size), 2 ** (genes) - 1)
43
+ for i in range(len(decimal)):
44
+ s = '{:0' + str(genes[i]) + 'b}'
45
+ gray_code += s.format(graycode.tc_to_gray_code(int(decimal[i])))
46
+
47
+ return cls(gray_code, x_min, x_max, genes, function)
48
+
49
+ @classmethod
50
+ def crossover(cls, individual1, individual2, mutation_chance, max_mutation=1):
51
+ k = np.random.randint(1, len(individual1.gray_code) - 1, 2)
52
+ while k[0] == k[1]:
53
+ k = np.random.randint(1, len(individual1.gray_code) - 1, 2)
54
+ k = np.sort(k)
55
+ new_gray1 = individual1.gray_code[:k[0]] + individual2.gray_code[k[0]:k[1]] + individual1.gray_code[k[1]:]
56
+ new_gray2 = individual2.gray_code[:k[0]] + individual1.gray_code[k[0]:k[1]] + individual2.gray_code[k[1]:]
57
+ return [
58
+ cls(new_gray1, individual1.x_min, individual1.x_max, individual1.genes,
59
+ individual1.function, mutation_chance, max_mutation),
60
+ cls(new_gray2, individual1.x_min, individual1.x_max, individual1.genes,
61
+ individual1.function, mutation_chance, max_mutation),
62
+ ]
63
+
64
+ def mutation(self, max_mutation=1):
65
+ if max_mutation > 0:
66
+ n = 1 + np.random.randint(1, max_mutation)
67
+ else:
68
+ n = 1
69
+ k = np.random.choice(len(self.gray_code), n, replace=False)
70
+ for ki in k:
71
+ b = bool(int(self.gray_code[ki]))
72
+ b = not b
73
+ b = str(int(b))
74
+ self.gray_code = self.gray_code[:ki] + b + self.gray_code[ki+1:]
75
+
76
+ def __lt__(self, other):
77
+ return self.f < other.f
78
+
79
+ def __le__(self, other):
80
+ return self.f <= other.f
81
+
82
+ def __gt__(self, other):
83
+ return self.f > other.f
84
+
85
+ def __ge__(self, other):
86
+ return self.f >= other.f
87
+
88
+
89
+ class GeneticAlgorithm:
90
+
91
+ def __init__(self, f, n, child_percent, mutation_chance, max_mutation, x_min, x_max, genes, t_max, printing=False):
92
+ self.f = f
93
+ self.n = n
94
+ self.child_percent = child_percent
95
+ self.mutation_chance = mutation_chance
96
+ self.max_mutation = max_mutation
97
+ self.x_min = np.array(x_min)
98
+ self.x_max = np.array(x_max)
99
+ self.genes = np.array(genes)
100
+ self.t_max = np.array(t_max)
101
+ self.printing = printing
102
+
103
+ self.rand_n_individual = np.vectorize(lambda x: x * self.random_individual(), signature='()->(n)')
104
+ self.generate_population = np.vectorize(lambda decimal: Individual.generate_from_decimal(
105
+ decimal, self.x_min, self.x_max, self.genes, self.f), signature='(n)->()')
106
+
107
+ def random_individual(self):
108
+ return np.random.randint(np.zeros(self.genes.size), 2 ** self.genes)
109
+
110
+ def start(self):
111
+ x = self.rand_n_individual(np.ones(self.n))
112
+ population = self.generate_population(x)
113
+ child_number = int(self.child_percent * self.n)
114
+
115
+ t = 0
116
+ while t <= self.t_max:
117
+ new_population = []
118
+ for i in range(child_number):
119
+ k = np.random.randint(0, self.n, 2)
120
+ while k[0] == k[1]:
121
+ k = np.random.randint(0, self.n, 2)
122
+ new_population += Individual.crossover(population[k[0]], population[k[1]],
123
+ self.mutation_chance, self.max_mutation)
124
+ population = np.append(population, np.array(new_population))
125
+ population.sort()
126
+ population = population[:self.n]
127
+ if self.printing:
128
+ print("Поколение {}: {} {}".format(t, population[0].real_x, population[0].f))
129
+ t += 1
130
+ return population[0].real_x
@@ -0,0 +1,127 @@
1
+ import numpy as np
2
+
3
+
4
+ class GoldDigger:
5
+
6
+ def __init__(self, x, function):
7
+ self.x = x
8
+ self.f = function(self.x)
9
+ self.ep_n = 0
10
+
11
+ def __lt__(self, other):
12
+ return self.f < other.f
13
+
14
+ def __le__(self, other):
15
+ return self.f <= other.f
16
+
17
+ def __gt__(self, other):
18
+ return self.f > other.f
19
+
20
+ def __ge__(self, other):
21
+ return self.f >= other.f
22
+
23
+ def __add__(self, other):
24
+ return self.f + other.f
25
+
26
+ def __radd__(self, other):
27
+ return self.f + other
28
+
29
+ def __truediv__(self, other):
30
+ return self.f / other
31
+
32
+ def update_function(self, function):
33
+ self.f = function(self.x)
34
+
35
+ def new_sigma_digger(self, x_min, x_max, sigma, function):
36
+ new_x = np.array([self.x[i] + np.random.normal(0, (x_max[i] - x_min[i]) * sigma) for i in range(self.x.size)])
37
+ new_x = np.clip(new_x, x_min, x_max)
38
+ return GoldDigger(new_x, function)
39
+
40
+
41
+
42
+ class GoldDiggersAlgorithm:
43
+
44
+ def __init__(self, f, n, k, l, u, a, b, sigma_b, sigma_e, Xmin, Xmax, m, t_max):
45
+ self.f = f
46
+ self.n = n
47
+ self.k = k
48
+ self.l = l
49
+ self.u = u
50
+ self.a = a
51
+ self.b = b
52
+ self.sigma_b = sigma_b
53
+ self.sigma_e = sigma_e
54
+ self.Xmin = np.array(Xmin)
55
+ self.Xmax = np.array(Xmax)
56
+ self.m = m
57
+ self.t_max = t_max
58
+ self.rand_mat = np.vectorize(lambda x: self.random_matrix(x, Xmin, Xmax), signature='()->(n)')
59
+ self.digger_init = np.vectorize(lambda x: GoldDigger(x, self.f), signature='(n)->()')
60
+
61
+ @staticmethod
62
+ def random_matrix(x, x_min, x_max):
63
+ return x * np.random.uniform(x_min, x_max)
64
+
65
+ def start(self):
66
+ x = self.rand_mat(np.ones(self.n))
67
+ population = self.digger_init(x)
68
+
69
+ t = 0
70
+ intervals = []
71
+ while t <= self.t_max:
72
+
73
+ x = self.rand_mat(np.ones(self.n))
74
+ in_interval = np.array([self.interval_in(xi, intervals) for xi in x])
75
+ if np.any(in_interval == True):
76
+ ind = np.where(in_interval == False)
77
+ new_x = x[ind]
78
+ if new_x.size:
79
+ population = np.append(population, self.digger_init(new_x))
80
+ ind = np.where(in_interval == True)
81
+ r = np.random.rand(ind[0].size)
82
+ rand_ind = np.where(r <= self.a)
83
+ ind = (ind[0][rand_ind])
84
+ x = x[ind]
85
+ if x.size:
86
+ population = np.append(population, self.digger_init(x))
87
+ else:
88
+ population = np.append(population, self.digger_init(x))
89
+
90
+ sigma = (((self.t_max - t) / self.t_max) ** self.m) * (self.sigma_b - self.sigma_e) + self.sigma_e
91
+
92
+ new_diggers = []
93
+ for digger in population:
94
+ for _ in range(self.k):
95
+ new_diggers.append(digger.new_sigma_digger(self.Xmin, self.Xmax, sigma, self.f))
96
+ population = np.append(population, new_diggers)
97
+ population = np.sort(population)
98
+
99
+ worst_diggers = population[self.n:]
100
+ r = np.random.rand(worst_diggers.size)
101
+ ind = np.where(r <= self.b)
102
+ worst_diggers = worst_diggers[ind]
103
+ for digger in worst_diggers:
104
+ intervals.append(
105
+ (digger.x - (self.Xmax - self.Xmin) * sigma, digger.x + (self.Xmax - self.Xmin) * sigma)
106
+ )
107
+ if len(intervals) > self.u:
108
+ intervals = intervals[len(intervals) - self.u - 1:len(intervals) - 1]
109
+ population = population[:self.n]
110
+ print("Поколение {}: {} {}".format(t, population[0].x, population[0].f))
111
+ t += 1
112
+ return population[0].x
113
+
114
+ @staticmethod
115
+ def interval_in(x, intervals):
116
+ for interval in intervals:
117
+ res = [x[i] >= interval[0][i] and x[i] <= interval[1][i] for i in range(len(x))]
118
+ if any(res):
119
+ return True
120
+ return False
121
+
122
+
123
+ def f(x):
124
+ return sum([(xi ** 4 - 16 * xi ** 2 + 5 *xi) / 2 for xi in x])
125
+
126
+ # gda = GoldDiggersAlgorithm(f, 15, 10, 10, 50, 0.5, 0.5, 0.5, 0.000001, [-5.12, -5.12, -5.12, -5.12, -5.12, -5.12, -5.12, -5.12, -5.12, -5.12], [5.12, 5.12, 5.12, 5.12, 5.12, 5.12, 5.12, 5.12, 5.12, 5.12], 2, 300)
127
+ # gda.start()
PyPharm/models.py CHANGED
@@ -2,10 +2,11 @@ from multiprocessing import shared_memory
2
2
 
3
3
  import numpy as np
4
4
  from scipy.integrate import solve_ivp, RK45
5
- from scipy.integrate._ivp.rk import rk_step, SAFETY, MAX_FACTOR, MIN_FACTOR
5
+ from scipy.integrate import simps
6
6
  from scipy.optimize import minimize
7
7
  from .country_optimization import CountriesAlgorithm
8
8
  from .country_optimization_v2 import CountriesAlgorithm_v2
9
+ from .genetic_optimization import GeneticAlgorithm
9
10
  from numba import njit
10
11
  import matplotlib.pyplot as plt
11
12
 
@@ -129,7 +130,22 @@ class BaseCompartmentModel:
129
130
  t_eval=t_eval
130
131
  )
131
132
  return self.last_result
132
-
133
+
134
+ def get_kinetic_params(self, t_max, d, compartment_number, max_step=0.01):
135
+ one_hour_result = self(t_max=1, d=d, compartment_number=compartment_number, max_step=max_step)
136
+ auc_1h = simps(one_hour_result.y[compartment_number], one_hour_result.t)
137
+ self(t_max=t_max, d=d, compartment_number=compartment_number, max_step=max_step)
138
+ auc = simps(self.last_result.y[compartment_number], self.last_result.t)
139
+ result_dict = {
140
+ 'c_max': self.last_result.y[compartment_number].max(),
141
+ 'V': self.volumes[compartment_number] if self.volumes is not None else None,
142
+ 'AUC': auc,
143
+ 'AUC_1h': auc_1h,
144
+ 'Cl': d / auc
145
+ }
146
+ return result_dict
147
+
148
+
133
149
  def load_data_from_list(self, x):
134
150
  if self.configuration_matrix_target:
135
151
  self.configuration_matrix[self.configuration_matrix_target] = x[:self.configuration_matrix_target_count]
@@ -201,7 +217,8 @@ class BaseCompartmentModel:
201
217
  self.c0 = np.array(c0)
202
218
  self.w = np.ones(self.teoretic_y.shape) if w is None else np.array(w)
203
219
 
204
- def optimize(self, method=None, max_step=0.01, metric='R2', **kwargs):
220
+ def optimize(self, method=None, user_method=None, method_is_func=True,
221
+ optimization_func_name='__call__', max_step=0.01, metric='R2', **kwargs):
205
222
  """
206
223
  Функция оптимизации модели
207
224
 
@@ -215,28 +232,41 @@ class BaseCompartmentModel:
215
232
  """
216
233
  self._optim = True
217
234
  f = lambda x: self._target_function(x, max_step=max_step, metric=metric)
218
- if method == 'country_optimization':
219
- CA = CountriesAlgorithm(
220
- f=f,
221
- memory_list=getattr(self, 'memory', None),
222
- **kwargs
223
- )
224
- CA.start()
225
- x = CA.countries[0].population[0].x
226
- elif method == 'country_optimization_v2':
227
- CA = CountriesAlgorithm_v2(
228
- f=f,
229
- **kwargs
230
- )
231
- CA.start()
232
- x = CA.countries[0].population[0].x
235
+ if user_method is not None:
236
+ if method_is_func:
237
+ x = user_method(f, **kwargs)
238
+ else:
239
+ optimization_obj = user_method(f, **kwargs)
240
+ x = getattr(optimization_obj, optimization_func_name)()
233
241
  else:
234
- res = minimize(
235
- fun=f,
236
- method=method,
237
- **kwargs
238
- )
239
- x = res.x
242
+ if method == 'country_optimization':
243
+ CA = CountriesAlgorithm(
244
+ f=f,
245
+ memory_list=getattr(self, 'memory', None),
246
+ **kwargs
247
+ )
248
+ CA.start()
249
+ x = CA.countries[0].population[0].x
250
+ elif method == 'country_optimization_v2':
251
+ CA = CountriesAlgorithm_v2(
252
+ f=f,
253
+ **kwargs
254
+ )
255
+ CA.start()
256
+ x = CA.countries[0].population[0].x
257
+ elif method == 'GA':
258
+ CA = GeneticAlgorithm(
259
+ f=f,
260
+ **kwargs
261
+ )
262
+ x = CA.start()
263
+ else:
264
+ res = minimize(
265
+ fun=f,
266
+ method=method,
267
+ **kwargs
268
+ )
269
+ x = res.x
240
270
  if self.configuration_matrix_target:
241
271
  self.configuration_matrix[self.configuration_matrix_target] = x[:self.configuration_matrix_target_count]
242
272
  if self.outputs_target:
@@ -311,8 +341,9 @@ class MagicCompartmentModel(BaseCompartmentModel):
311
341
  if self.need_magic_optimization:
312
342
  self.magic_coefficient = x[-1]
313
343
 
314
- def optimize(self, method=None, max_step=0.01, **kwargs):
315
- x = super().optimize(method, max_step, **kwargs)
344
+ def optimize(self, method=None, user_method=None, method_is_func=True,
345
+ optimization_func_name='__call__', max_step=0.01, **kwargs):
346
+ x = super().optimize(method, user_method, method_is_func, optimization_func_name, max_step, **kwargs)
316
347
  if self.need_magic_optimization:
317
348
  self.magic_coefficient = x[-1]
318
349
  self.need_magic_optimization = False
@@ -577,8 +608,9 @@ class ReleaseCompartmentModel(BaseCompartmentModel):
577
608
  self.c0 = np.array(c0)
578
609
  self.w = np.ones(self.teoretic_y.shape) if w is None else np.array(w)
579
610
 
580
- def optimize(self, method=None, max_step=0.01, **kwargs):
581
- x = super().optimize(method, max_step, **kwargs)
611
+ def optimize(self, method=None, user_method=None, method_is_func=True,
612
+ optimization_func_name='__call__', max_step=0.01, **kwargs):
613
+ x = super().optimize(method, user_method, method_is_func, optimization_func_name, max_step, **kwargs)
582
614
  s = self.configuration_matrix_target_count + self.outputs_target_count + self.volumes_target_count
583
615
  if self.release_parameters_target:
584
616
  self.release_parameters[self.release_parameters_target] = x[s:s + self.release_parameters_target_count]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pypharm
3
- Version: 1.3.2
3
+ Version: 1.3.5
4
4
  Summary: Module for solving pharmacokinetic problems
5
5
  Home-page: https://github.com/Krash13/PyPharm
6
6
  Author: Krash13
@@ -143,6 +143,75 @@ model.optimize(
143
143
  При оптимизации, вектор неизвестных это
144
144
  x = [configuration_matrix (неизвестные), outputs(неизвестные), volumes(неизвестные)]
145
145
 
146
+ Кроме того, вы можете использовать генетический алгоритм:
147
+ ```python
148
+ model.optimize(
149
+ method='GA',
150
+ x_min=[0.00001, 0.001, 0.01, 1, 1],
151
+ x_max=[1, 2, 1, 10, 3],
152
+ genes=[16, 17, 16, 20, 16],
153
+ n=100,
154
+ child_percent=0.3,
155
+ mutation_chance=0.5,
156
+ max_mutation=5,
157
+ t_max=300,
158
+ max_step=0.5,
159
+ printing=True,
160
+ )
161
+ ```
162
+
163
+ Вы даже можете использовать свой собственный алгоритм, если это необходимо
164
+
165
+ ```python
166
+ # CountriesAlgorithm - ваш класс алгоритма
167
+ # start - функция запуска алгоритма
168
+ # важно, чтобы ваша функция запуска возвращала numpy.array
169
+
170
+ model.optimize(
171
+ user_method=CountriesAlgorithm,
172
+ method_is_func=False,
173
+ optimization_func_name='start',
174
+ Xmin=[0.00001, 0.001, 0.01, 1, 1], #ваши настроечные параметры
175
+ Xmax=[1, 2, 1, 10, 3],
176
+ genes=[16, 17, 16, 20, 16],
177
+ M=20,
178
+ N=25,
179
+ n=[1, 10],
180
+ max_mutation=8,
181
+ m=[1, 8],
182
+ k=8,
183
+ l=3,
184
+ ep=[0.2, 0.4],
185
+ tmax=200,
186
+ max_step=0.5,
187
+ printing=True
188
+ )
189
+ ```
190
+
191
+ или
192
+
193
+ ```python
194
+ # my_alg - ваша функция алгоритма, важно, чтобы она принимала только целевую функцию
195
+
196
+ model.optimize(
197
+ user_method=my_alg,
198
+ Xmin=[0.00001, 0.001, 0.01, 1, 1], #ваши настроечные параметры
199
+ Xmax=[1, 2, 1, 10, 3],
200
+ genes=[16, 17, 16, 20, 16],
201
+ M=20,
202
+ N=25,
203
+ n=[1, 10],
204
+ max_mutation=8,
205
+ m=[1, 8],
206
+ k=8,
207
+ l=3,
208
+ ep=[0.2, 0.4],
209
+ tmax=200,
210
+ max_step=0.5,
211
+ printing=True
212
+ )
213
+ ```
214
+
146
215
  **4) Модель MagicCompartmentModel**
147
216
 
148
217
  Данная модель необходима нам для тех случаев,
@@ -349,6 +418,77 @@ printing=True,
349
418
  When optimizing, the vector of unknowns is
350
419
  x = [configuration_matrix (unknown), outputs(unknown), volumes(unknown)]
351
420
 
421
+ In addition, you can use a genetic algorithm:
422
+
423
+ ```python
424
+
425
+ model.optimize(
426
+ method='GA',
427
+ x_min=[0.00001, 0.001, 0.01, 1, 1],
428
+ x_max=[1, 2, 1, 10, 3],
429
+ genes=[16, 17, 16, 20, 16],
430
+ n=100,
431
+ percentage of descendants=0.3,
432
+ the probability of mutation =0.5,
433
+ max_mutation=5,
434
+ t_max=300,
435
+ max_step=0.5,
436
+ print=True,
437
+ )
438
+ ```
439
+
440
+ You can even use your own algorithm if necessary.
441
+
442
+ ```python
443
+ # Countryalgorithm - your class is an algorithm
444
+ # start - start the algorithm
445
+ # it is important that your application aroused the interest of numpy.array
446
+
447
+ model.optimize(
448
+ user_method=country Countryalgorithm,
449
+ method_is_func=False,
450
+ optimization_func_name='start',
451
+ Xmin=[0.00001, 0.001, 0.01, 1, 1], # your desktop settings
452
+ Xmax Max=[1, 2, 1, 10, 3],
453
+ genes=[16, 17, 16, 20, 16],
454
+ M=20,
455
+ N=25,
456
+ n=[1, 10],
457
+ max_mutation=8,
458
+ m=[1, 8],
459
+ k=8,
460
+ l=3,
461
+ ep=[0,2, 0,4],
462
+ tmax=200,
463
+ max_step=0.5,
464
+ print=True
465
+ )
466
+ ```
467
+
468
+ or
469
+
470
+ ```python
471
+ # my_alg is your algorithm function, it is important that it accepts only the target function
472
+
473
+ model.optimize(
474
+ custom method=my_alg,
475
+ Xmin=[0.00001, 0.001, 0.01, 1, 1], # your desktop settings
476
+ Xmax Max=[1, 2, 1, 10, 3],
477
+ genes=[16, 17, 16, 20, 16],
478
+ M=20,
479
+ N=25,
480
+ n=[1, 10],
481
+ max_mutation=8,
482
+ m=[1, 8],
483
+ k=8,
484
+ l=3,
485
+ ep=[0,2, 0,4],
486
+ tmax=200,
487
+ max_step=0.5,
488
+ print=True
489
+ )
490
+ ```
491
+
352
492
  **4) The MagicCompartmentModel model**
353
493
 
354
494
  We need this model for those cases
@@ -0,0 +1,11 @@
1
+ PyPharm/__init__.py,sha256=hxhMRlWpLMARQV-ZNYkmvhQ9gCYI18an75vlySWjA6s,90
2
+ PyPharm/country_optimization.py,sha256=3fnnAJfdLgD0RP8qyJzHBuPDHcPljcLPQM9oqNip1r8,19664
3
+ PyPharm/country_optimization_v2.py,sha256=3d2mt15DXdr1V3soIJS51xuCv6uzH8pirah1RnI5--8,13156
4
+ PyPharm/country_optimization_v3.py,sha256=-3slM5MwSmiG6rD7p9ycbUQPdt4hd5bcEwpSxjb3A7U,17034
5
+ PyPharm/genetic_optimization.py,sha256=EC_pEWwL-ufCQd71zBhCeAB6-Sh1fijv7F3L0bWCz3I,5036
6
+ PyPharm/gold_digger_optimization.py,sha256=mln67sAYxkwzFqZ9Ylild1F25VuaruXRPaUMOGT5gIM,4449
7
+ PyPharm/models.py,sha256=VQlSLGzV3k7mNKiLAIKV29mc6ka6IakmUtEt10cBcq8,33066
8
+ pypharm-1.3.5.dist-info/METADATA,sha256=zodKyZM_l7ORmGwqdtFfqZJ4kpHLiAhexzqYPbvpfA4,17574
9
+ pypharm-1.3.5.dist-info/WHEEL,sha256=OqRkF0eY5GHssMorFjlbTIq072vpHpF60fIQA6lS9xA,92
10
+ pypharm-1.3.5.dist-info/top_level.txt,sha256=yybfSkKw8q1G3aEcnlfVL7_L9ufGFSAYZnpc7q6oYJk,8
11
+ pypharm-1.3.5.dist-info/RECORD,,
@@ -1,8 +0,0 @@
1
- PyPharm/__init__.py,sha256=hxhMRlWpLMARQV-ZNYkmvhQ9gCYI18an75vlySWjA6s,90
2
- PyPharm/country_optimization.py,sha256=WsjfAWAWbxRnUUfBiMi1VatCSVbru7F1_G6kQBRVyA0,20452
3
- PyPharm/country_optimization_v2.py,sha256=3d2mt15DXdr1V3soIJS51xuCv6uzH8pirah1RnI5--8,13156
4
- PyPharm/models.py,sha256=ecT0cFCbcmDL1jYuQE2IMZ7aPFZXRf63FAuJzJnugxs,31380
5
- pypharm-1.3.2.dist-info/METADATA,sha256=kVzRdLrOj8_pXPtFgXYhBReVZKju5YTscVzfmDdFJPo,14464
6
- pypharm-1.3.2.dist-info/WHEEL,sha256=OqRkF0eY5GHssMorFjlbTIq072vpHpF60fIQA6lS9xA,92
7
- pypharm-1.3.2.dist-info/top_level.txt,sha256=yybfSkKw8q1G3aEcnlfVL7_L9ufGFSAYZnpc7q6oYJk,8
8
- pypharm-1.3.2.dist-info/RECORD,,