pypharm 1.6.2__py3-none-any.whl → 1.6.3__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.
- PyPharm/models/compartment_models.py +3 -3
- PyPharm/models/pbpk.py +3 -3
- {pypharm-1.6.2.dist-info → pypharm-1.6.3.dist-info}/METADATA +2 -1
- pypharm-1.6.3.dist-info/RECORD +9 -0
- PyPharm/algorithms/__init__.py +0 -0
- PyPharm/algorithms/country_optimization.py +0 -469
- PyPharm/algorithms/country_optimization_v2.py +0 -330
- PyPharm/algorithms/country_optimization_v3.py +0 -428
- PyPharm/algorithms/genetic_optimization.py +0 -130
- PyPharm/algorithms/gold_digger_optimization.py +0 -127
- PyPharm/country_optimization.py +0 -470
- PyPharm/country_optimization_v2.py +0 -330
- PyPharm/country_optimization_v3.py +0 -426
- PyPharm/genetic_optimization.py +0 -130
- PyPharm/gold_digger_optimization.py +0 -127
- PyPharm/models.py +0 -638
- pypharm-1.6.2.dist-info/RECORD +0 -21
- {pypharm-1.6.2.dist-info → pypharm-1.6.3.dist-info}/WHEEL +0 -0
- {pypharm-1.6.2.dist-info → pypharm-1.6.3.dist-info}/top_level.txt +0 -0
|
@@ -4,9 +4,9 @@ import numpy as np
|
|
|
4
4
|
from scipy.integrate import solve_ivp, RK45
|
|
5
5
|
from scipy.integrate import simps
|
|
6
6
|
from scipy.optimize import minimize
|
|
7
|
-
from
|
|
8
|
-
from
|
|
9
|
-
from
|
|
7
|
+
from krashemit.algorithms.country_optimization import CountriesAlgorithm
|
|
8
|
+
from krashemit.algorithms.country_optimization_v2 import CountriesAlgorithm_v2
|
|
9
|
+
from krashemit.algorithms.genetic_optimization import GeneticAlgorithm
|
|
10
10
|
from numba import njit
|
|
11
11
|
import matplotlib.pyplot as plt
|
|
12
12
|
|
PyPharm/models/pbpk.py
CHANGED
|
@@ -3,9 +3,9 @@ import matplotlib
|
|
|
3
3
|
import numpy as np
|
|
4
4
|
from scipy.integrate import solve_ivp, LSODA
|
|
5
5
|
from scipy.optimize import minimize
|
|
6
|
-
from
|
|
7
|
-
from
|
|
8
|
-
from
|
|
6
|
+
from krashemit.algorithms.country_optimization import CountriesAlgorithm
|
|
7
|
+
from krashemit.algorithms.country_optimization_v2 import CountriesAlgorithm_v2
|
|
8
|
+
from krashemit.algorithms.genetic_optimization import GeneticAlgorithm
|
|
9
9
|
from PyPharm.constants import MODEL_CONST, ANIMALS
|
|
10
10
|
from numba import njit, types, cfunc
|
|
11
11
|
from numba.typed import Dict
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pypharm
|
|
3
|
-
Version: 1.6.
|
|
3
|
+
Version: 1.6.3
|
|
4
4
|
Summary: Module for solving pharmacokinetic problems
|
|
5
5
|
Home-page: https://github.com/Krash13/PyPharm
|
|
6
6
|
Author: Krash13
|
|
@@ -13,6 +13,7 @@ Classifier: License :: OSI Approved :: BSD License
|
|
|
13
13
|
Classifier: Operating System :: OS Independent
|
|
14
14
|
Requires-Python: >=3.9
|
|
15
15
|
Description-Content-Type: text/markdown
|
|
16
|
+
Requires-Dist: krashemit (>=1.0.0)
|
|
16
17
|
Requires-Dist: numpy (>=1.22.1)
|
|
17
18
|
Requires-Dist: scipy (<=1.13.0)
|
|
18
19
|
Requires-Dist: numba (>=0.58.1)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
PyPharm/__init__.py,sha256=2HYYSesc-mjv-S9Q1Jm8yiLCZNmUGvlYCOWC8znJKok,158
|
|
2
|
+
PyPharm/constants.py,sha256=KovwTSSkiGh9o0Hf-yoqw3H7GxC_YmawunlWMHtSK98,3869
|
|
3
|
+
PyPharm/models/__init__.py,sha256=uCPwMYWOLdxiMZJ4eeVzee6Nrafot5gbCVsHXnHWuM0,196
|
|
4
|
+
PyPharm/models/compartment_models.py,sha256=LjMn8T7IVUywRj0rNnS0VQm26ZmPtveoF_X74Cg2KsE,51317
|
|
5
|
+
PyPharm/models/pbpk.py,sha256=ENkhi_BLxZ2s2tnrgCHmlJljZxBfvofdWSHtT3VKUM4,30645
|
|
6
|
+
pypharm-1.6.3.dist-info/METADATA,sha256=KkFIqDUAxcvC9yAf1F3x6qkrphYkxtL6TTeIh68T-2Y,23011
|
|
7
|
+
pypharm-1.6.3.dist-info/WHEEL,sha256=OqRkF0eY5GHssMorFjlbTIq072vpHpF60fIQA6lS9xA,92
|
|
8
|
+
pypharm-1.6.3.dist-info/top_level.txt,sha256=yybfSkKw8q1G3aEcnlfVL7_L9ufGFSAYZnpc7q6oYJk,8
|
|
9
|
+
pypharm-1.6.3.dist-info/RECORD,,
|
PyPharm/algorithms/__init__.py
DELETED
|
File without changes
|
|
@@ -1,469 +0,0 @@
|
|
|
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, memory_list=None):
|
|
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
|
-
self.memory_list = memory_list
|
|
367
|
-
for i in range(M):
|
|
368
|
-
self.countries.append(Country(self.Xmin, self.Xmax, N, self.f))
|
|
369
|
-
|
|
370
|
-
def start(self):
|
|
371
|
-
ti = 0
|
|
372
|
-
motion = 0
|
|
373
|
-
trade = 0
|
|
374
|
-
war = 0
|
|
375
|
-
epedemic = 0
|
|
376
|
-
if self.memory_list is not None:
|
|
377
|
-
self.memory_list[0] = False
|
|
378
|
-
while ti <= self.tmax:
|
|
379
|
-
ti += 1
|
|
380
|
-
for country in self.countries:
|
|
381
|
-
if country.action is None:
|
|
382
|
-
country.select_action(self.countries)
|
|
383
|
-
for country in self.countries:
|
|
384
|
-
if country.action == 0:
|
|
385
|
-
motion += 1
|
|
386
|
-
country.motion(
|
|
387
|
-
function=self.f,
|
|
388
|
-
Xmin=self.Xmin,
|
|
389
|
-
Xmax=self.Xmax
|
|
390
|
-
)
|
|
391
|
-
elif country.action == 1:
|
|
392
|
-
trade += 1
|
|
393
|
-
Country.trade(
|
|
394
|
-
country1=country,
|
|
395
|
-
country2=country.ally,
|
|
396
|
-
k=self.k
|
|
397
|
-
)
|
|
398
|
-
elif country.action == 2:
|
|
399
|
-
war += 1
|
|
400
|
-
Country.war(
|
|
401
|
-
country1=country,
|
|
402
|
-
country2=country.enemy,
|
|
403
|
-
l=self.l
|
|
404
|
-
)
|
|
405
|
-
elif country.action == 3:
|
|
406
|
-
epedemic += 1
|
|
407
|
-
country.epedemic(
|
|
408
|
-
elite=self.ep[0],
|
|
409
|
-
dead=self.ep[1],
|
|
410
|
-
Xmin=self.Xmin,
|
|
411
|
-
Xmax=self.Xmax,
|
|
412
|
-
function=self.f,
|
|
413
|
-
p_max=self.p[1],
|
|
414
|
-
)
|
|
415
|
-
self.countries = [country for country in self.countries if country.population]
|
|
416
|
-
self.countries = sorted(self.countries, key=attrgetter('avg_function'))
|
|
417
|
-
if not self.countries:
|
|
418
|
-
break
|
|
419
|
-
f_min = self.countries[0].avg_function
|
|
420
|
-
f_max = self.countries[-1].avg_function
|
|
421
|
-
if f_min == f_max:
|
|
422
|
-
self.countries = sorted(self.countries, key=attrgetter('best_function'))
|
|
423
|
-
result = self.countries[0].population[0]
|
|
424
|
-
break
|
|
425
|
-
e_individuals = []
|
|
426
|
-
for country in self.countries:
|
|
427
|
-
if len(country.population) == 1:
|
|
428
|
-
e_individuals.append(country.population[0])
|
|
429
|
-
continue
|
|
430
|
-
if country.population:
|
|
431
|
-
country.reproduction(
|
|
432
|
-
n_min=self.n[0],
|
|
433
|
-
n_max=self.n[1],
|
|
434
|
-
p_min=self.p[0],
|
|
435
|
-
p_max=self.p[1],
|
|
436
|
-
f_min=f_min,
|
|
437
|
-
f_max=f_max,
|
|
438
|
-
ti=ti,
|
|
439
|
-
t_max=self.tmax,
|
|
440
|
-
function=self.f,
|
|
441
|
-
Xmin=self.Xmin,
|
|
442
|
-
Xmax=self.Xmax
|
|
443
|
-
)
|
|
444
|
-
country.extinction(
|
|
445
|
-
m_min=self.m[0],
|
|
446
|
-
m_max=self.m[1],
|
|
447
|
-
f_min=f_min,
|
|
448
|
-
f_max=f_max
|
|
449
|
-
)
|
|
450
|
-
self.countries = [country for country in self.countries if country.population]
|
|
451
|
-
for individual in e_individuals:
|
|
452
|
-
random_country = self.countries[random.randint(0, len(self.countries) - 1)]
|
|
453
|
-
random_country.population.append(individual)
|
|
454
|
-
random_country.sort_population()
|
|
455
|
-
self.countries = sorted(self.countries, key=attrgetter('best_function'))
|
|
456
|
-
if not self.countries:
|
|
457
|
-
break
|
|
458
|
-
result = self.countries[0].population[0]
|
|
459
|
-
|
|
460
|
-
if self.printing:
|
|
461
|
-
print(f"{ti}) Лучшее решение: {result.x} - {result.f}, Стран осталось: {len(self.countries)}, Движение/Обмен/Войны/Эпидемии: {motion}/{trade}/{war}/{epedemic}")
|
|
462
|
-
print(f"Общее количество особей: {sum([len(country.population) for country in self.countries])}")
|
|
463
|
-
|
|
464
|
-
if self.memory_list is not None:
|
|
465
|
-
self.memory_list[0] = ti
|
|
466
|
-
for i in range(len(result.x)):
|
|
467
|
-
self.memory_list[i + 1] = float(result.x[i])
|
|
468
|
-
self.memory_list[-1] = float(result.f)
|
|
469
|
-
return (result.x, result.f, False, ti)
|