Привет!
Я полный новичок в программировании, и мне нужно оптимизировать алгоритм так, чтобы он работал намного быстрее. У меня есть система дифференциальных уравнений для функций u, i, v с четырьмя параметрами beta, delta, p, c. Сначала я задал значения коэффициентов и с помощью численного метода получил значения всех трех функций, записанные в три соответствующих массива. Затем я пытаюсь решить обратную задачу: у нас есть три массива значений функций, и, используя эти значения, мы пытаемся найти коэффициенты. Для этого я написал функцию get_coefficients(u_values, i_values, v_values, t_end). Я реализовал наиглупейший способ. Я установил 4 отрезка, в пределах которых параметры могут изменяться. И тупо прогнал значения коэффициентов через четыре цикла while и с постоянным шагом.
ОС -Windows
Python 3.8
Пишу в jupiter
Код:
В результате функция сработала корректно, но, конечно, работает она очень медленно, несмотря на то, что отрезки крайне малы. Есть ли какие-то готовые известные алгоритмы оптимизации или функции в каких-то библиотеках, чтобы это работало быстрее, и желательно работало на полуинтервалах [0, + бесконечность). Спасибо за любую помощь!
Я полный новичок в программировании, и мне нужно оптимизировать алгоритм так, чтобы он работал намного быстрее. У меня есть система дифференциальных уравнений для функций u, i, v с четырьмя параметрами beta, delta, p, c. Сначала я задал значения коэффициентов и с помощью численного метода получил значения всех трех функций, записанные в три соответствующих массива. Затем я пытаюсь решить обратную задачу: у нас есть три массива значений функций, и, используя эти значения, мы пытаемся найти коэффициенты. Для этого я написал функцию get_coefficients(u_values, i_values, v_values, t_end). Я реализовал наиглупейший способ. Я установил 4 отрезка, в пределах которых параметры могут изменяться. И тупо прогнал значения коэффициентов через четыре цикла while и с постоянным шагом.
ОС -Windows
Python 3.8
Пишу в jupiter
Код:
Python:
EPSILON = 1*pow(10, -8)
# Задаем параметры
beta = 1.59*pow(10, -8)
delta = pow(10, -6)
p = 23.91
c = pow(10, -8)
# Задаем начальные условия
u = 70000
i = 0
v = 7000
# Задаем временной интервал и шаг
t = 0
t_end = 100
dt = 0.01
# Создаем списки для сохранения значений u,i,v и времени
time = []
u_values = []
i_values = []
v_values = []
while t < t_end:
# Подсчет инкрементов для u, i, v
du1 = dt * (- beta * u * v)
di1 = dt * (beta * u * v - delta * i)
dv1 = dt * (p * i - c * v)
du2 = dt * (- beta * (u + du1/2) * (v + dv1/2))
di2 = dt * (beta * (u + du1/2) * (v + dv1/2) - delta * (i + di1/2))
dv2 = dt * (p * (i + di1/2) - c * (v + dv1/2))
du3 = dt * (- beta * (u + du2/2) * (v + dv2/2))
di3 = dt * (beta * (u + du2/2) * (v + dv2/2) - delta * (i + di2/2))
dv3 = dt * (p * (i + di2/2) - c * (v + dv2/2))
du4 = dt * (- beta * (u + du3) * (v + dv3))
di4 = dt * (beta * (u + du3) * (v + dv3) - delta * (i + di3))
dv4 = dt * (p * (i + di3) - c * (v + dv3))
# Обновляем значения u, i, v
u += (du1 + 2*du2 + 2*du3 + du4) / 6
i += (di1 + 2*di2 + 2*di3 + di4) / 6
v += (dv1 + 2*dv2 + 2*dv3 + dv4) / 6
# Сохраняем текущие значения
time.append(t)
u_values.append(u)
i_values.append(i)
v_values.append(v)
# Обновляем время
t += dt
def get_coefficients(u_values, i_values, v_values, t_end):
n = 5
coeff = []
points = []
u_val = []
i_val = []
v_val = []
beta_begin = 1.59*pow(10, -8)
delta_begin = 0.1*pow(10, -6)
p_begin = 20
c_begin = 0.1*pow(10, -8)
beta_end = 1.69*pow(10, -8)
delta_end = 1.1*pow(10, -6)
p_end = 24.91
c_end = 1.1*pow(10, -8)
dbeta = 1*pow(10, -10)
ddelta = 1*pow(10, -7)
dp = 0.01
dc = 1*pow(10, -9)
beta_f = beta_begin
delta_f = delta_begin
p_f = p_begin
c_f = c_begin
previous = 0
for i in range(n):
points.append(previous + t_end/5)
previous = points[-1]
while beta_f <= beta_end:
print(beta_f)
while delta_f <= delta_end:
while p_f <= p_end:
while c_f <= c_end:
u_val = []
i_val = []
v_val = []
u_example = []
i_example = []
v_example = []
# Задаем начальные условия
u_f = 70000
i_f = 0
v_f = 7000
# Задаем временной интервал и шаг
t_f = 0
dt_f = 0.01
# Создаем списки для сохранения значений u,i,v и времени
time_f = []
while t_f < t_end:
# Подсчет инкрементов для u, i, v
du1_f = dt_f * (- beta_f * u_f * v_f)
di1_f = dt_f * (beta_f * u_f * v_f - delta_f * i_f)
dv1_f = dt_f * (p_f * i_f - c_f * v_f)
du2_f = dt_f * \
(- beta_f * (u_f + du1_f/2) * (v_f + dv1_f/2))
di2_f = dt_f * (beta_f * (u_f + du1_f/2) *
(v_f + dv1_f/2) - delta_f * (i_f + di1_f/2))
dv2_f = dt_f * (p_f * (i_f + di1_f/2) -
c_f * (v_f + dv1_f/2))
du3_f = dt_f * \
(- beta_f * (u_f + du2_f/2) * (v_f + dv2_f/2))
di3_f = dt_f * (beta_f * (u_f + du2_f/2) *
(v_f + dv2_f/2) - delta_f * (i_f + di2_f/2))
dv3_f = dt_f * (p_f * (i_f + di2_f/2) -
c_f * (v_f + dv2_f/2))
du4_f = dt_f * \
(- beta_f * (u_f + du3_f) * (v_f + dv3_f))
di4_f = dt_f * (beta_f * (u_f + du3_f) *
(v_f + dv3_f) - delta_f * (i_f + di3_f))
dv4_f = dt_f * (p_f * (i_f + di3_f) -
c_f * (v_f + dv3_f))
# Обновляем значения u, i, v
u_f += (du1_f + 2*du2_f + 2*du3_f + du4_f) / 6
i_f += (di1_f + 2*di2_f + 2*di3_f + di4_f) / 6
v_f += (dv1_f + 2*dv2_f + 2*dv3_f + dv4_f) / 6
# Сохраняем текущие значения
time_f.append(t_f)
u_val.append(u_f)
i_val.append(i_f)
v_val.append(v_f)
# Обновляем время
t_f += dt_f
index = []
for i in range(len(time_f)):
for j in range(len(points)):
if abs(time_f[i] - points[j]) < 0.001:
index.append(i)
u_standard = [u_values[index[0]], u_values[index[1]],
u_values[index[2]], u_values[index[3]]]
i_standard = [i_values[index[0]], i_values[index[1]],
i_values[index[2]], i_values[index[3]]]
v_standard = [v_values[index[0]], v_values[index[1]],
v_values[index[2]], v_values[index[3]]]
u_example = [u_val[index[0]], u_val[index[1]],
u_val[index[2]], u_val[index[3]]]
i_example = [i_val[index[0]], i_val[index[1]],
i_val[index[2]], i_val[index[3]]]
v_example = [v_val[index[0]], v_val[index[1]],
v_val[index[2]], v_val[index[3]]]
count = 0
for i in range(n-1):
if (u_standard[i] - u_example[i]) < EPSILON and (i_standard[i] - i_example[i]
) < EPSILON and (v_standard[i] - v_example[i]) < EPSILON:
count += 1
if count == n-1:
coeff.append([beta_f, delta_f, p_f, c_f])
c_f += dc
c_f = c_begin
p_f += dp
p_f = p_begin
delta_f += ddelta
delta_f = delta_begin
beta_f += dbeta
print(coeff)
get_coefficients(u_values, i_values, v_values, t_end)
В результате функция сработала корректно, но, конечно, работает она очень медленно, несмотря на то, что отрезки крайне малы. Есть ли какие-то готовые известные алгоритмы оптимизации или функции в каких-то библиотеках, чтобы это работало быстрее, и желательно работало на полуинтервалах [0, + бесконечность). Спасибо за любую помощь!