pypharm 1.3.6__py3-none-any.whl → 1.4.1__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.
@@ -0,0 +1,330 @@
1
+ import random
2
+ import numpy as np
3
+ from math import ceil
4
+
5
+
6
+ def random_matrix(x, x_min, x_max):
7
+ return x * np.random.uniform(x_min, x_max)
8
+
9
+ def check_population(country):
10
+ return bool(country.population.size)
11
+
12
+ def get_avg(country):
13
+ return country.avg_function
14
+
15
+ def get_best(country):
16
+ return country.best_function
17
+
18
+ vector_check_population = np.vectorize(check_population, signature='()->()')
19
+ vector_min = np.vectorize(min, signature='(),()->()')
20
+ vector_max = np.vectorize(max, signature='(),()->()')
21
+ vector_avg = np.vectorize(get_avg, signature='()->()')
22
+ vector_best = np.vectorize(get_best, signature='()->()')
23
+
24
+ class Individual:
25
+
26
+ def __init__(self, x, function):
27
+ self.x = x
28
+ self.f = function(self.x)
29
+ self.ep_n = 0
30
+
31
+ def __lt__(self, other):
32
+ return self.f < other.f
33
+
34
+ def __le__(self, other):
35
+ return self.f <= other.f
36
+
37
+ def __gt__(self, other):
38
+ return self.f > other.f
39
+
40
+ def __ge__(self, other):
41
+ return self.f >= other.f
42
+
43
+ def __add__(self, other):
44
+ return self.f + other.f
45
+
46
+ def __radd__(self, other):
47
+ return self.f + other
48
+
49
+ def __truediv__(self, other):
50
+ return self.f / other
51
+
52
+ def update_function(self, function):
53
+ self.f = function(self.x)
54
+
55
+ @classmethod
56
+ def crossing(cls, individual1, individual2, p, function, Xmin, Xmax):
57
+ alpha = p
58
+ c_min = vector_min(individual1.x, individual2.x)
59
+ c_max = vector_max(individual1.x, individual2.x)
60
+ I = c_max - c_min
61
+ new_x = np.random.uniform(c_min - I * alpha, c_max + I * alpha)
62
+ new_x = np.clip(new_x, Xmin, Xmax)
63
+ return [cls(new_x, function)]
64
+
65
+ def mutation(self, Xmin, Xmax, function, pmax):
66
+ self.ep_n += 1
67
+ self.x = self.x + pmax * np.random.uniform(-self.x, self.x) / self.ep_n
68
+ np.clip(self.x, Xmin, Xmax)
69
+ self.update_function(function)
70
+
71
+
72
+ class Country:
73
+
74
+ def __init__(self, Xmin, Xmax, N, function):
75
+ x_min = np.random.uniform(Xmin, Xmax)
76
+ x_max = np.random.uniform(x_min, Xmax)
77
+ self.population = []
78
+ ind_init = np.vectorize(lambda x: Individual(x, function), signature='(n)->()')
79
+ rand_mat = np.vectorize(lambda x: random_matrix(x, x_min, x_max), signature='()->(n)')
80
+ v = rand_mat(np.ones(N))
81
+ self.population = ind_init(v)
82
+ self.sort_population()
83
+ self.action = None
84
+ self.enemy = None
85
+ self.ally = None
86
+
87
+ @property
88
+ def best_function(self):
89
+ return self.population[0].f
90
+
91
+ @property
92
+ def avg_function(self):
93
+ return np.average(self.population)
94
+
95
+ def update_population(self, function):
96
+ for individual in self.population:
97
+ individual.update_function(function)
98
+
99
+ def sort_population(self):
100
+ self.population = np.sort(self.population)
101
+
102
+ def reproduction(self, n_min, n_max, p_min, p_max, f_min, f_max, ti, t_max, function, Xmin, Xmax):
103
+ n = ceil((n_max - n_min) * (f_max - self.avg_function) / (f_max - f_min) + n_min)
104
+ n = np.clip(n, n_min, n_max)
105
+ p = (p_max - p_min) * (1 - ti / t_max) * (self.avg_function - f_min) / (f_max - f_min) + p_min
106
+ p = np.clip(p, p_min, p_max)
107
+ new_individuals = np.array([])
108
+ for i in range(n):
109
+ parents = np.random.choice(self.population, 2, replace=False)
110
+ new_individuals = np.concatenate([new_individuals, Individual.crossing(parents[0], parents[1], p, function, Xmin, Xmax)])
111
+ self.population = np.concatenate([self.population, new_individuals])
112
+ self.sort_population()
113
+
114
+ def extinction(self, m_min, m_max, f_min, f_max):
115
+ m = int((m_max - m_min) * (self.avg_function - f_min) / (f_max - f_min) + m_min)
116
+ m = m if m <= m_max else m_max
117
+ m = m if m >= m_min else m_min
118
+ self.population = self.population[:-m]
119
+
120
+ def select_action(self, countries):
121
+ self.action = random.randint(0, 3)
122
+ if self.action == 1:
123
+ ally_list = [country for country in countries if country.action is None and country != self]
124
+ if ally_list:
125
+ self.ally = ally_list.pop(random.randint(0, len(ally_list) - 1))
126
+ self.ally.action = 1
127
+ self.ally.ally = self
128
+ else:
129
+ self.action = random.choice([0, 3])
130
+ if self.action == 2:
131
+ enemy_list = [country for country in countries if country.action is None and country != self]
132
+ if enemy_list:
133
+ self.enemy = enemy_list.pop(random.randint(0, len(enemy_list) - 1))
134
+ self.enemy.action = 2
135
+ self.enemy.enemy = self
136
+ else:
137
+ self.action = random.choice([0, 3])
138
+
139
+ def epedemic(self, elite, dead, function, Xmin, Xmax, p_max):
140
+ n_elite = ceil(elite * len(self.population))
141
+ n_dead = ceil(dead * len(self.population))
142
+ self.population = self.population[:-n_dead]
143
+ for individual in self.population[n_elite:]:
144
+ individual.mutation(Xmin, Xmax, function, p_max)
145
+ self.sort_population()
146
+ self.action = None
147
+
148
+ # def sabotage(self, n_copy):
149
+ # for i in range(n_copy):
150
+ # self.enemy.population.append(copy.copy(self.population[0]))
151
+ # self.action = None
152
+ # self.enemy = None
153
+
154
+ def motion(self, function, Xmin, Xmax):
155
+ x_best = self.population[0].x
156
+ for i in range(1, len(self.population)):
157
+ self.population[i].x = self.population[i].x + np.random.uniform(0, 2, self.population[i].x.size) * (x_best - self.population[i].x)
158
+ np.clip(self.population[i].x, Xmin, Xmax)
159
+ self.update_population(function)
160
+ self.sort_population()
161
+ self.action = None
162
+
163
+ @staticmethod
164
+ def trade(country1, country2, k):
165
+ if country1.population.size <= k or country2.population.size <= k:
166
+ k = min(country1.population.size, country2.population.size) // 2
167
+ indexes1 = np.random.choice(country1.population.size, k, replace=False)
168
+ indexes2 = np.random.choice(country2.population.size, k, replace=False)
169
+ country2.population = np.concatenate([country2.population, country1.population[indexes1]])
170
+ country1.population = np.concatenate([country1.population, country2.population[indexes2]])
171
+ country1.population = np.delete(country1.population, indexes1)
172
+ country2.population = np.delete(country2.population, indexes2)
173
+ country1.sort_population()
174
+ country2.sort_population()
175
+ country1.action = None
176
+ country2.action = None
177
+ country1.ally = None
178
+ country2.ally = None
179
+
180
+ @staticmethod
181
+ def war(country1, country2, l):
182
+ if country1.population.size <= l or country2.population.size <= l:
183
+ l = min(country1.population.size, country2.population.size)
184
+ indexes1 = np.random.choice(country1.population.size, l, replace=False)
185
+ indexes2 = np.random.choice(country2.population.size, l, replace=False)
186
+ war_list1 = country1.population[indexes1]
187
+ war_list2 = country2.population[indexes2]
188
+ country1.population = np.delete(country1.population, indexes1)
189
+ country2.population = np.delete(country2.population, indexes2)
190
+ wins1 = np.where(war_list1 > war_list2)
191
+ wins2 = np.where(war_list2 > war_list2)
192
+ if wins1[0].size > wins2[0].size:
193
+ np.concatenate([country1.population, war_list1])
194
+ np.concatenate([country1.population, war_list2])
195
+ elif wins2[0].size > wins1[0].size:
196
+ np.concatenate([country2.population, war_list1])
197
+ np.concatenate([country2.population, war_list2])
198
+ else:
199
+ np.concatenate([country1.population, war_list1])
200
+ np.concatenate([country2.population, war_list2])
201
+ country1.sort_population()
202
+ country2.sort_population()
203
+ country1.action = None
204
+ country2.action = None
205
+ country1.enemy = None
206
+ country2.enemy = None
207
+
208
+
209
+ class CountriesAlgorithm_v2:
210
+
211
+ def __init__(self, f, Xmin, Xmax, M, N, n, p, m, k, l, ep, tmax, printing=False):
212
+ self.f = f
213
+ self.Xmin = Xmin
214
+ self.Xmax = Xmax
215
+ self.n = n
216
+ self.p = p
217
+ self.m = m
218
+ self.k = k
219
+ self.l = l
220
+ self.ep = ep
221
+ self.tmax = tmax
222
+ self.printing = printing
223
+ country_init = np.vectorize(lambda x: Country(self.Xmin, self.Xmax, N, self.f))
224
+ self.countries = country_init(np.ones(M))
225
+
226
+ def sort(self, method):
227
+ if method == 'avg_function':
228
+ avg_arr = vector_avg(self.countries)
229
+ indexes = np.argsort(avg_arr)
230
+ self.countries = self.countries[indexes]
231
+ else:
232
+ avg_arr = vector_best(self.countries)
233
+ indexes = np.argsort(avg_arr)
234
+ self.countries = self.countries[indexes]
235
+
236
+ def start(self):
237
+ ti = 0
238
+ motion = 0
239
+ trade = 0
240
+ war = 0
241
+ epedemic = 0
242
+ while ti <= self.tmax:
243
+ ti += 1
244
+ for country in self.countries:
245
+ if country.action is None:
246
+ country.select_action(self.countries)
247
+ for country in self.countries:
248
+ if country.action == 0:
249
+ motion += 1
250
+ country.motion(
251
+ function=self.f,
252
+ Xmin=self.Xmin,
253
+ Xmax=self.Xmax
254
+ )
255
+ elif country.action == 1:
256
+ trade += 1
257
+ Country.trade(
258
+ country1=country,
259
+ country2=country.ally,
260
+ k=self.k
261
+ )
262
+ elif country.action == 2:
263
+ war += 1
264
+ Country.war(
265
+ country1=country,
266
+ country2=country.enemy,
267
+ l=self.l
268
+ )
269
+ elif country.action == 3:
270
+ epedemic += 1
271
+ country.epedemic(
272
+ elite=self.ep[0],
273
+ dead=self.ep[1],
274
+ Xmin=self.Xmin,
275
+ Xmax=self.Xmax,
276
+ function=self.f,
277
+ p_max=self.p[1],
278
+ )
279
+ indexes = np.where(vector_check_population(self.countries) == True)
280
+ self.countries = self.countries[indexes]
281
+ self.sort('avg_function')
282
+ if not self.countries.size:
283
+ break
284
+ f_min = self.countries[0].avg_function
285
+ f_max = self.countries[-1].avg_function
286
+ if f_min == f_max:
287
+ self.sort('best_function')
288
+ result = self.countries[0].population[0]
289
+ break
290
+ e_individuals = []
291
+ for country in self.countries:
292
+ if country.population.size == 1:
293
+ e_individuals.append(country.population[0])
294
+ continue
295
+ if country.population.size:
296
+ country.reproduction(
297
+ n_min=self.n[0],
298
+ n_max=self.n[1],
299
+ p_min=self.p[0],
300
+ p_max=self.p[1],
301
+ f_min=f_min,
302
+ f_max=f_max,
303
+ ti=ti,
304
+ t_max=self.tmax,
305
+ function=self.f,
306
+ Xmin=self.Xmin,
307
+ Xmax=self.Xmax
308
+ )
309
+ country.extinction(
310
+ m_min=self.m[0],
311
+ m_max=self.m[1],
312
+ f_min=f_min,
313
+ f_max=f_max
314
+ )
315
+ indexes = np.where(vector_check_population(self.countries) == True)
316
+ self.countries = self.countries[indexes]
317
+ for individual in e_individuals:
318
+ random_country = self.countries[random.randint(0, len(self.countries) - 1)]
319
+ random_country.population = np.append(random_country.population, individual)
320
+ random_country.sort_population()
321
+ self.sort('best_function')
322
+ if not self.countries.size:
323
+ break
324
+ result = self.countries[0].population[0]
325
+
326
+ if self.printing:
327
+ print(f"{ti}) Лучшее решение: {result.x} - {result.f}, Стран осталось: {len(self.countries)}, Движение/Обмен/Войны/Эпидемии: {motion}/{trade}/{war}/{epedemic}")
328
+ print(f"Общее количество особей: {sum([len(country.population) for country in self.countries])}")
329
+ return (result.x, result.f, False, ti)
330
+