{"id":412947,"date":"2024-06-29T22:50:24","date_gmt":"2024-06-29T22:50:24","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=412947"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=412947","title":{"rendered":"<span>\u041e\u0431\u0443\u0447\u0435\u043d\u0438\u0435 \u0441 \u043f\u043e\u0434\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u0438\u0435\u043c \u043d\u0430 Python: \u041f\u0440\u0438\u043c\u0435\u0440 \u043d\u0435 \u0438\u0437 \u00ab\u043a\u0430\u0447\u0430\u043b\u043a\u0438\u00bb<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h2>\u041f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0437\u0430\u0434\u0430\u0447\u0438<\/h2>\n<p>\u041e\u0431\u0443\u0447\u0435\u043d\u0438\u0435 \u0441 \u043f\u043e\u0434\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u0438\u0435\u043c \u043c\u043e\u043b\u043e\u0434\u0430\u044f \u0438 \u0431\u0443\u0440\u043d\u043e \u0440\u0430\u0441\u0442\u0443\u0449\u0430\u044f \u0434\u0438\u0441\u0446\u0438\u043f\u043b\u0438\u043d\u0430. \u042d\u0442\u043e \u043e\u0431\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u043e \u043f\u0440\u0438\u0432\u0435\u043b\u043e \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e\u0431 \u044d\u0442\u043e\u043c \u043c\u0430\u043b\u043e \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c \u0438 \u043f\u043e\u0447\u0442\u0438 \u043d\u0435\u0442 \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0435. \u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e, \u0435\u0441\u043b\u0438 \u0434\u0435\u043b\u043e \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043d\u043e-\u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430, \u0438 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0437\u0430\u0434\u0430\u0447 \u043d\u0435 \u0438\u0437 \u0430\u0440\u0441\u0435\u043d\u0430\u043b\u0430 <em>Open Gym<\/em>. \u0421\u0442\u0430\u043b\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u043a\u0430\u043a \u0440\u0435\u0448\u0430\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438 RL \u0432 <strong>\u0434\u0440\u0443\u0433\u0438\u0445 <\/strong>\u0441\u0440\u0435\u0434\u0430\u0445.<\/p>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e \u0432\u0430\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043a\u0430\u043a \u044f \u043d\u0430\u0434\u0435\u044e\u0441\u044c, \u0443\u0431\u0435\u0440\u0435\u0436\u0435\u0442 \u0432\u0430\u0441 \u043e\u0442 \u0447\u0430\u0441\u0442\u0438 \u0448\u0438\u0448\u0435\u043a \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0449\u0438\u0445\u0441\u044f \u043d\u0430 \u044d\u0442\u043e\u043c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u043c \u043f\u0443\u0442\u0438.<\/p>\n<p>\u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c \u0437\u0430\u0434\u0430\u0447\u0443, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043d\u0430\u043d\u043e \u0440\u043e\u0431\u043e\u0442 \u0441 \u0430\u043d\u0442\u0438\u0431\u0438\u043e\u0442\u0438\u043a\u043e\u043c \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u0434\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u043a \u0441\u043a\u043e\u043f\u043b\u0435\u043d\u0438\u044e \u043f\u0430\u0442\u043e\u0433\u0435\u043d\u043d\u044b\u0445 \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439 \u0434\u043b\u044f \u0438\u0445 \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u043c Reinforsment Learning \u043e\u0442 Keras \u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0434\u043b\u044f \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438.<\/p>\n<pre><code class=\"python\">!pip install keras-rl2 !pip install celluloid<\/code><\/pre>\n<pre><code class=\"python\"># \u0411\u0430\u0437\u043e\u0432\u044b\u0435 \u041c\u043e\u0434\u0443\u043b\u0438 import time    # \u043c\u043e\u0434\u0443\u043b\u044c \u0434\u043b\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0441\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c\u0438 \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0438\u0441\u0442\u0438\u043a\u0430\u043c\u0438 import random import numpy as np  # \u041c\u043e\u0434\u0443\u043b\u0438 Keras from tensorflow.keras.models import Sequential, Model from tensorflow.keras.layers import Dense, Activation, Flatten, Input, Concatenate from tensorflow.keras.optimizers import Adam  # \u041c\u043e\u0434\u0443\u043b\u0438 Keras-RL2 import rl.core as krl from rl.agents import DDPGAgent from rl.memory import SequentialMemory from rl.random import OrnsteinUhlenbeckProcess  # \u041c\u043e\u0434\u0443\u043b\u0438 \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 from celluloid import Camera import matplotlib.pyplot as plt      from matplotlib import rc rc('animation', html='jshtml') %matplotlib inline<\/code><\/pre>\n<h2>\u0421\u0440\u0435\u0434\u0430<\/h2>\n<p>\u0414\u043b\u044f \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u0441 \u043f\u043e\u0434\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u0438\u0435\u043c \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0441\u0440\u0435\u0434\u0430 \u0438 \u0430\u0433\u0435\u043d\u0442. <\/p>\n<p>\u0421\u0440\u0435\u0434\u043e\u0439 \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0431\u0443\u0434\u0435\u0442 \u043c\u0438\u0433\u0440\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u0432 \u0442\u043a\u0430\u043d\u044f\u0445 \u043f\u0430\u0442\u043e\u0433\u0435\u043d\u044b. \u0418\u0445 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0440\u043e\u0435\u0432\u043e\u043c\u0443 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044e.<\/p>\n<p>\u0420\u043e\u0435\u0432\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u043e \u043c\u043e\u0434\u0435\u043b\u044c\u044e \u0412\u0438\u0447\u0435\u043a\u0430 (1995 \u0433.).\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u044d\u0442\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043c\u043e\u0436\u043d\u043e \u0438\u043c\u0438\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043a\u043e\u043f\u043b\u0435\u043d\u0438\u044f \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439, \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0441\u0442\u0430\u0438 \u043f\u0442\u0438\u0446 \u0438\u043b\u0438 \u043a\u043e\u0441\u044f\u043a\u0430 \u0440\u044b\u0431, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u043a\u0430\u043a \u0438\u0437 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u043f\u0440\u0430\u0432\u0438\u043b \u043f\u043e\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u0430\u043c\u043e \u0443\u043f\u043e\u0440\u044f\u0434\u043e\u0447\u0435\u043d\u043d\u044b\u0435 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0412\u043e\u0437\u044c\u043c\u0435\u043c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u0438\u0437 \u0441\u0442\u0430\u0442\u044c\u0438\u00a0<a href=\"https:\/\/nuancesprog.ru\/p\/11626\/\" rel=\"noopener noreferrer nofollow\">\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0439 \u043c\u0430\u0442\u0435\u0440\u0438\u0438 \u043d\u0430 Python<\/a>. \u0418 \u043f\u0435\u0440\u0435\u043f\u0438\u0448\u0435\u043c \u0435\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043d\u043e-\u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434. \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0432\u044b \u0443\u0436\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u044b \u0441 \u041e\u041e\u041f \u0434\u043b\u044f Python.<\/p>\n<pre><code class=\"python\"># \u0418\u043c\u0438\u0442\u0430\u0446\u0438\u044f \u0440\u043e\u0435\u0432\u043e\u0433\u043e \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f class Colony:   # \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0447\u0430\u0441\u0442\u0438\u0446\u044b    x : np.ndarray   y : np.ndarray   # \u0443\u0433\u043e\u043b \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0447\u0430\u0441\u0442\u0438\u0446\u044b   theta : np.ndarray   # \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0447\u0430\u0441\u0442\u0438\u0446\u044b \u043f\u043e \u043e\u0441\u044f\u043c   vx : np.ndarray   vy : np.ndarray    # \u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440   def __init__(self,N):     self.reset(N)    # \u0440\u0430\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 N \u0447\u0430\u0441\u0442\u0438\u0446 \u043d\u0430 \u043f\u043b\u043e\u0449\u0430\u0434\u043a\u0435 LxL   def reset(self,N):     # \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0447\u0430\u0441\u0442\u0438\u0446      self.x = np.random.rand(N,1)*L     self.y = np.random.rand(N,1)*L     # \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0438 \u043e\u0441\u0435\u0432\u044b\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0447\u0430\u0441\u0442\u0438\u0446 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e      # \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u0439 \u043b\u0438\u043d\u0435\u0439\u043d\u043e\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 v0     self.theta = 2 * np.pi * np.random.rand(N,1)     self.vx = v0 * np.cos(self.theta)     self.vy = v0 * np.sin(self.theta)   # \u0428\u0430\u0433 \u0438\u043c\u0438\u0442\u0430\u0446\u0438\u0438   def step(self):     # \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435     self.x += self.vx*dt     self.y += self.vy*dt     # \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u043d\u044b\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u0439     self.x = self.x % L     self.y = self.y % L     # \u043d\u0430\u0439\u0442\u0438 \u0441\u0440\u0435\u0434\u043d\u0438\u0439 \u0443\u0433\u043e\u043b \u0441\u043e\u0441\u0435\u0434\u0435\u0439 \u0432 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0435 R     mean_theta = self.theta     for b in range(N):         neighbors = (self.x-self.x[b])**2+(self.y-self.y[b])**2 &lt; R**2         sx = np.sum(np.cos(self.theta[neighbors]))         sy = np.sum(np.sin(self.theta[neighbors]))         mean_theta[b] = np.arctan2(sy, sx)     # \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0433\u043e \u043e\u0442\u043a\u043b\u043e\u043d\u0435\u043d\u0438\u044f     self.theta = mean_theta + eta*(np.random.rand(N,1)-0.5)     # \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438     self.vx = v0 * np.cos(self.theta)     self.vy = v0 * np.sin(self.theta)     return self.theta    # \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0447\u0430\u0441\u0442\u0438\u0446 \u0432 \u0432\u043d\u0443\u0442\u0440\u0438 \u0440\u0430\u0434\u0438\u0443\u0441\u0430 r \u043e\u0442 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 x,y   def observe(self,x,y,r):     return (self.x-x)**2+(self.y-y)**2 &lt; r**2   # \u0412\u044b\u0432\u0435\u0441\u0442\u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0447\u0430\u0441\u0442\u0438\u0446\u044b i   def print(self,i):     return print(self.x[i],self.y[i])   # \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0447\u0430\u0441\u0442\u0438\u0446   def get_bacteria(self):     return self.x, self.y    # \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0439 \u0447\u0430\u0441\u0442\u0438\u0446   def get_theta(self):     return self.theta <\/code><\/pre>\n<p>\u041e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u043f\u043e\u0441\u043b\u0443\u0436\u0438\u0442 \u043d\u0430\u043c \u0434\u043b\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0441\u0440\u0435\u0434\u044b\u00a0<em>state<\/em>. \u041d\u0435 \u043f\u0443\u0442\u0430\u0439\u0442\u0435\u00a0<em>observation<\/em>\u00a0\u0438\u00a0<em>state<\/em>. \u041d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u043c\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435\u00a0<strong><em>observation<\/em><\/strong>, \u044d\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e, \u0447\u0442\u043e \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u0442 \u0430\u0433\u0435\u043d\u0442. \u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c\u00a0<em>state<\/em>\u00a0\u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u0432\u0441\u044f \u0441\u0440\u0435\u0434\u0430: \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0432\u0441\u0435\u0445 \u043d\u0430\u0448\u0438\u0445 \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439.<\/p>\n<p>\u0414\u043b\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0432 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u043a\u043b\u0430\u0441\u0441\u0430\u00a0<em>action_space<\/em>\u00a0\u0438\u00a0<em>observation_space<\/em>\u00a0\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u00a0<em>action<\/em>\u00a0\u0430\u0433\u0435\u043d\u0442\u0430 \u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0440\u0435\u0434\u044b\u00a0<em>observation<\/em>.<\/p>\n<p>\u0418\u0445 \u043d\u0430\u0434\u043e \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u043e\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 rl.Space. \u0414\u043b\u044f action_space \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b:<\/p>\n<ul>\n<li>\n<p><strong>sample()<\/strong>\u00a0&#8212; \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0435 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0447\u0438\u0441\u043b\u043e \u0438\u0437 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430 [-1,1)<\/p>\n<\/li>\n<li>\n<p><strong>contains(x)<\/strong>\u00a0&#8212; \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 x \u043d\u0430 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u044c.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0435 shape \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0444\u043e\u0440\u043c\u0443 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439<\/p>\n<pre><code class=\"python\"># action - \u0441\u043a\u0430\u043b\u044f\u0440 \u043e\u0442 -1 \u0434\u043e 1 class actionSpace(krl.Space):   def __init__(self):     self.shape = (1,)   def sample(self, seed=None):     if seed: random.seed(seed)     return random.triangular(-1,1)   def contains(self, x):     return  abs(x) &lt;= 1  # observation - \u043c\u0430\u0441\u0441\u0438\u0432  # \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u043d\u0435 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c. class observationSpace(krl.Space):   def __init__(self):     self.shape = (5,) #   def sample(self, seed=None): pass   def contains(self, x): pass<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0440\u0435\u0434\u0443 \u043d\u0430\u043c \u043d\u0430\u0434\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u044f \u0435\u0435 \u0438\u0437 \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 \u0441\u0440\u0435\u0434\u044b\u00a0<em>rl.Env<\/em>\u00a0\u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u043e\u0439 \u043a\u0435\u0440\u0430\u0441. \u042d\u0442\u043e \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441, \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 \u0437\u0430\u0434\u0443\u043c\u0430\u043d\u043d\u043e\u0439 \u0441\u0440\u0435\u0434\u043e\u0439 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0435\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u044b:<\/p>\n<ul>\n<li>\n<p><strong>reset()<\/strong>\u00a0&#8212; &#171;\u0441\u043e\u0442\u0432\u043e\u0440\u0435\u043d\u0438\u0435 \u043c\u0438\u0440\u0430&#187;<\/p>\n<\/li>\n<li>\n<p><strong>step(action)<\/strong>\u00a0&#8212; \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043c\u0438\u0440\u0430 \u043d\u0430 \u0448\u0430\u0433\u0435 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 action<\/p>\n<\/li>\n<li>\n<p><strong>render()<\/strong>\u00a0&#8212; \u0432\u044b\u0432\u043e\u0434 \u043b\u044e\u0431\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043f\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044e \u043c\u0438\u0440\u0430 \u043d\u0430 \u0434\u0430\u043d\u043d\u043e\u043c \u0448\u0430\u0433\u0435.<\/p>\n<\/li>\n<li>\n<p><strong>close()<\/strong>\u00a0&#8212; \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 \u043a\u043b\u0430\u0441\u0441\u0430<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u043a\u043b\u0430\u0441\u0441\u0435 \u0441\u0440\u0435\u0434\u044b \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u00a0<em>state<\/em>, \u043d\u0430\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u0435\u00a0<em>observation<\/em>, \u043d\u0430\u0433\u0440\u0430\u0434\u0443\u00a0<em>reward<\/em>.<\/p>\n<p>\u0412\u00a0<em>observation<\/em>\u00a0\u043f\u043e\u0434\u0430\u0434\u0438\u043c 5 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445:<\/p>\n<ol>\n<li>\n<p>\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e &#171;\u0437\u0430\u0445\u0432\u0430\u0447\u0435\u043d\u043d\u044b\u0445&#187; \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439 \u0432\u043d\u0443\u0442\u0440\u0438 \u0440\u0430\u0434\u0438\u0443\u0441\u0430 R<\/p>\n<\/li>\n<li>\n<p>\u0421\u0440\u0435\u0434\u043d\u0438\u0439 \u0443\u0433\u043e\u043b \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439 \u0432\u043d\u0443\u0442\u0440\u0438 R<\/p>\n<\/li>\n<li>\n<p>\u0423\u0433\u043e\u043b \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0430 \u0446\u0435\u043d\u0442\u0440 \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439 \u0432\u043d\u0443\u0442\u0440\u0438 R<\/p>\n<\/li>\n<li>\n<p>\u0423\u0433\u043e\u043b \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0430 \u0446\u0435\u043d\u0442\u0440 \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u0440\u0443\u0433\u0430 R-1.5R<\/p>\n<\/li>\n<li>\n<p>\u0422\u0435\u043a\u0443\u0449\u0438\u0439 \u0443\u0433\u043e\u043b \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0430\u043d\u043e \u0440\u043e\u0431\u043e\u0442\u0430<\/p>\n<p>\u041d\u0430\u0433\u0440\u0430\u0434\u0430 &#8212; \u0442\u043e\u0447\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432\u0430\u0448\u0435\u0433\u043e \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f. \u041d\u0430\u0433\u0440\u0430\u0434\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0435. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0441\u0442\u0440\u043e\u0433\u043e \u0448\u0442\u0440\u0430\u0444\u043e\u0432\u0430\u0442\u044c \u0437\u0430 \u043f\u043e\u0442\u0435\u0440\u044e \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439, \u0442\u0435\u043c \u0441\u0442\u0440\u043e\u0436\u0435 \u0447\u0435\u043c \u0438\u0445 \u043c\u0435\u043d\u044c\u0448\u0435 \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 R. \u0422\u0430\u043a \u0436\u0435, \u0440\u0435\u0448\u0438\u043c \u043f\u043e\u043e\u0449\u0440\u044f\u0442\u044c \u0437\u0430 \u043f\u0440\u0438\u043e\u0431\u0440\u0435\u0442\u0435\u043d\u0438\u0435 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0442\u043e\u0447\u0435\u043a.<\/p>\n<p>\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0435\u043c,- \u0431\u0443\u0434\u0435\u0442 \u0443\u0433\u043e\u043b \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u043d\u0430\u043d\u043e \u0440\u043e\u0431\u043e\u0442\u0430. \u0412\u0441\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0434\u0435\u043b\u0435\u043d\u0438\u0435\u043c \u043d\u0430\u00a0<em>Pi<\/em>.<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"python\"># \u043d\u0430\u0448\u0430 \"\u0447\u0430\u0448\u0435\u0447\u043a\u0430 \u041f\u0435\u0442\u0440\u0438\" class Cure(krl.Env):   # \u0438\u043c\u0438\u0442\u0438\u0440\u0443\u0435\u043c\u0430\u044f \u043a\u043e\u043b\u043e\u043d\u0438\u044f   bacteria : Colony   # \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430\u043d\u043e \u0440\u043e\u0431\u043e\u0442\u0430   x: float   y: float   theta: float  # \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430\u043d\u043e \u0440\u043e\u0431\u043e\u0442\u0430   R: float  # \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439 \u043d\u0430\u043d\u043e \u0440\u043e\u0431\u043e\u0442\u043e\u043c   n_bacteria : int  # \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0432\u0438\u0434\u0438\u043c\u044b\u0445 \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439 \u0434\u043b\u044f rewarda   # \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440   def __init__(self):     self.bacteria = Colony(N)     self.reward_range = (-1,1) #(-np.inf, np.inf)     self.action_space = actionSpace()     self.observation_space = observationSpace()     self.R = observation_R     self.reset()    #  \u0424\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u0435\u043a\u0442\u043e\u0440\u0430 \u043e\u0431\u0437\u043e\u0440\u0430 observation.   #  \u0422\u043e \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 R \u043e\u0442 \u0440\u043e\u0431\u043e\u0442\u0430.    def observe_area(self):     # \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0441\u043e\u0441\u0435\u0434\u0435\u0439 \u0432 \u0440\u0430\u0434\u0438\u0443\u0441\u0435 R     observe_bacteria = self.bacteria.observe(self.x,self.y,self.R)     # \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0441\u043e\u0441\u0435\u0434\u0435\u0439 \u0432 \u0440\u0430\u0434\u0438\u0443\u0441\u0435 R*1.5     observe_far_bacteria = self.bacteria.observe(self.x,self.y,self.R*1.5)     observe_far_bacteria=np.array(np.bitwise_and(observe_far_bacteria,np.invert (observe_bacteria)))      observation = np.zeros(5)     # \u043f\u043e\u0434\u0430\u0434\u0438\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043e\u0441\u0435\u0434\u0435\u0439         n_bacteria = np.sum(observe_bacteria)     observation[0] = n_bacteria\/20      # \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0435\u043c \u0438 \u043f\u043e\u0434\u0430\u0434\u0438\u043c \u0441\u0440\u0435\u0434\u043d\u0435\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0439 \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u0445 \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439     sx = np.sum(np.cos(self.bacteria.theta[observe_bacteria]))     sy = np.sum(np.sin(self.bacteria.theta[observe_bacteria]))     observation[1] = np.arctan2(sy, sx)\/np.pi     # \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0435\u043c \u0438 \u043f\u043e\u0434\u0430\u0434\u0438\u043c \u0441\u0440\u0435\u0434\u043d\u0435\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0442 \u0440\u043e\u0431\u043e\u0442\u0430 \u0434\u043e \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u044b\u0445 \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439     sx = np.sum(self.bacteria.x[observe_bacteria]-self.x)     sy = np.sum(self.bacteria.y[observe_bacteria]-self.y)     observation[2] = np.arctan2(sy, sx)\/np.pi     # \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0435\u043c \u0438 \u043f\u043e\u0434\u0430\u0434\u0438\u043c \u0441\u0440\u0435\u0434\u043d\u0435\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0442 \u0440\u043e\u0431\u043e\u0442\u0430 \u0434\u043e \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u044b\u0445 \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439     sx = np.sum(self.bacteria.x[observe_far_bacteria]-self.x)     sy = np.sum(self.bacteria.y[observe_far_bacteria]-self.y)     observation[3] = np.arctan2(sy, sx)\/np.pi     if n_bacteria:       observation[4]=self.theta\/np.pi # \u043f\u043e\u0434\u0430\u0434\u0438\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430\u043d\u043e\u0440\u043e\u0431\u043e\u0442\u0430     return np.sum(observe_bacteria), observation    # \u0441\u0442\u0430\u0440\u0442 \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u0438   def reset(self):     self.bacteria.reset(N)     self.x = .5*L     self.y = .5*L     self.theta = actionSpace().sample()     self.n_bacteria , observation = self.observe_area()     return observation        # \u0448\u0430\u0433 \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u0438   def step(self,action):     action = action * 3.2#np.pi     #  \u0414\u043b\u044f \u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043f\u0440\u0438 \u043f\u043e\u043f\u0430\u0434\u0430\u043d\u0438\u0438 \u043d\u0430 \"\u0447\u0438\u0441\u0442\u0443\u044e \u0432\u043e\u0434\u0443\"      #  \u043f\u0440\u043e\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u044e \u043d\u0435 \u0432\u044b\u043f\u0443\u0441\u043a\u0430\u044f \u0435\u0435 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u0435\u0442\u0438     while True:       # \u0448\u0430\u0433 \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u0438 \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439       self.bacteria.step()       # \u0448\u0430\u0433 \u0440\u043e\u0431\u043e\u0442\u0430       self.theta = np.sum(action) #% (2*np.pi)       self.x = self.x + dt*v0 * np.cos(self.theta)       self.y = self.y + dt*v0 * np.sin(self.theta)       self.x = self.x  % L       self.y = self.y  % L       # \u043e\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435       nBacteria, observation = self.observe_area()       if np.sum(observation)!=0: break       if self.n_bacteria > 0: break      delta = nBacteria - self.n_bacteria     if delta&lt;0:       reward = 50 * delta\/self.n_bacteria     elif delta>0 and self.n_bacteria:       reward = 1+delta     elif nBacteria>0:       reward = 1             elif nBacteria == 0:       reward = 0     else:        reward = nBacteria     done = nBacteria > N\/7     self.n_bacteria = nBacteria     return observation, reward, done, {}    # \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0440\u043e\u0431\u043e\u0442\u0430   def get_position(self):     return self.x, self.y, self.R   # \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0432\u0441\u0435\u0445 \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439   def get_bacteria(self):     return self.bacteria.get_bacteria()   # \u043e\u0442\u0440\u0430\u0437\u0438\u0442\u044c \u043e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e      def render(self, mode='human', close=False):     #print(self.n_bacteria)     pass   # \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u044e   def close(self): pass     <\/code><\/pre>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u044d\u0442\u0430\u043f\u0435, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0441\u0440\u0435\u0434\u044b \u0438 \u043f\u0440\u043e\u0438\u0433\u0440\u0430\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0435 \u044d\u043f\u0438\u0437\u043e\u0434\u044b. <\/p>\n<figure class=\"float full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/553\/115\/f5f\/553115f5feb8b937b7fcfad9fcbbd08a.gif\" alt=\"\u041f\u0440\u043e\u0438\u0433\u0440\u044b\u0448 \u044d\u043f\u0438\u0437\u043e\u0434\u043e\u0432\" title=\"\u041f\u0440\u043e\u0438\u0433\u0440\u044b\u0448 \u044d\u043f\u0438\u0437\u043e\u0434\u043e\u0432\" width=\"640\" height=\"360\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/553\/115\/f5f\/553115f5feb8b937b7fcfad9fcbbd08a.gif\"\/><figcaption>\u041f\u0440\u043e\u0438\u0433\u0440\u044b\u0448 \u044d\u043f\u0438\u0437\u043e\u0434\u043e\u0432<\/figcaption><\/figure>\n<p>\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 \u044d\u043f\u0438\u0437\u043e\u0434\u043e\u0432 \u0434\u0430\u0441\u0442 \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0441 \u043a\u0430\u043a\u0438\u043c \u0440\u0430\u0437\u043d\u043e\u043e\u0431\u0440\u0430\u0437\u0438\u0435\u043c \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0439 \u0443\u0441\u043f\u0435\u0432\u0430\u0435\u0442 \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u0442\u044c\u0441\u044f \u043d\u0430\u0448 \u0440\u043e\u0431\u043e\u0442. \u0412 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u044d\u0442\u043e\u0433\u043e, \u0440\u0435\u0433\u0443\u043b\u0438\u0440\u0443\u0435\u043c: \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439; \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u043b\u043e\u0449\u0430\u0434\u043a\u0438; \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u044d\u043f\u043e\u0445.<\/p>\n<p>\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432 \u043d\u043e\u0443\u0442\u0431\u0443\u043a\u0435 <a href=\"https:\/\/colab.research.google.com\/drive\/12fjHeRR5WmBmOXqGovuihBE47pLIw49q#scrollTo=l-0aP0cPFmxK\" rel=\"noopener noreferrer nofollow\">Google Collab<\/a>.<\/p>\n<h2>\u0410\u0433\u0435\u043d\u0442 \u0438 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u0421\u0440\u0435\u0434\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0430. \u041e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0430\u0433\u0435\u043d\u0442\u0430.<\/p>\n<p>\u041d\u0430\u0448 \u0430\u0433\u0435\u043d\u0442 &#8212; \u043d\u0430\u043d\u043e \u0440\u043e\u0431\u043e\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0434\u0432\u0438\u0433\u0430\u0442\u044c\u0441\u044f \u0441 \u0442\u043e\u0439 \u0436\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c\u044e, \u0447\u0442\u043e \u0438 \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0438, \u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0435\u0433\u043e \u0443\u0433\u043b\u043e\u0432\u044b\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c\u00a0<em>action<\/em>. \u0420\u043e\u0431\u043e\u0442 &#171;\u0432\u0438\u0434\u0438\u0442&#187; \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u0435 \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0438 \u0438 \u0434\u043e\u043b\u0436\u0435\u043d \u0434\u0432\u0438\u0433\u0430\u0442\u044c\u0441\u044f \u0437\u0430 \u043d\u0438\u043c\u0438 \u0434\u043e\u0441\u0442\u0438\u0433\u0430\u044f \u043e\u0447\u0430\u0433\u0430 \u043f\u043e\u0440\u0430\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434\u00a0<strong>Deep Deterministic Policy Gradient (DDPG)<\/strong>, \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u043a\u0430\u043a\u00a0<em>DQN<\/em>\u00a0\u0434\u043b\u044f \u043d\u0435\u043f\u0440\u0435\u0440\u044b\u0432\u043d\u044b\u0445 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439. \u041c\u044b \u043f\u043e\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043e\u0431\u0443\u0447\u0430\u0435\u043c 2 \u0441\u0435\u0442\u0438\u00a0<strong>\u0410\u043a\u0442\u0435\u0440\u0430<\/strong>(\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435\u00a0<em>action<\/em>) \u0438\u00a0<strong>\u041a\u0440\u0438\u0442\u0438\u043a\u0430<\/strong>(\u043e\u0446\u0435\u043d\u0438\u0432\u0430\u0435\u0442 \u0432\u043e\u0437\u043d\u0430\u0433\u0440\u0430\u0436\u0434\u0435\u043d\u0438\u0435\u00a0<em>reward<\/em>).<\/p>\n<p>\u0414\u043b\u044f \u0442\u0440\u0435\u043d\u0438\u0440\u043e\u0432\u043a\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f\u00a0<em>keras-rl<\/em>\u00a0\u043a\u043b\u0430\u0441\u0441\u00a0<em>DDPGAgent<\/em>. \u041e\u043d \u0431\u0435\u0440\u0435\u0442 \u043d\u0430 \u0441\u0435\u0431\u044f \u0432\u0441\u044e \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e, \u0430 \u043d\u0430\u043c \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0440\u043e\u0447\u0435\u043a \u043a\u043e\u0434\u0430 \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \u041e\u041e\u041f \u0432\u0435\u043b\u0438\u043a\u0430\u044f \u0441\u0438\u043b\u0430!<\/p>\n<pre><code class=\"python\"> # \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0440\u0435\u0434\u0443 \u0438 \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 env = Cure() np.random.seed(123) assert len(env.action_space.shape) == 1 nb_actions = env.action_space.shape[0]  # \u041f\u043e\u0441\u0442\u0440\u043e\u0438\u043c \u043c\u043e\u0434\u0435\u043b\u044c \u0430\u043a\u0442\u0435\u0440\u0430. \u041f\u043e\u0434\u0430\u0435\u043c \u0441\u0440\u0435\u0434\u0443, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 actor = Sequential() actor.add(Flatten(input_shape=(1,) + env.observation_space.shape)) actor.add(Dense(4, use_bias=True)) actor.add(Activation('relu')) actor.add(Dense(4, use_bias=True)) actor.add(Activation('relu')) actor.add(Dense(nb_actions, use_bias=True)) actor.add(Activation('tanh')) print(actor.summary())  # \u041f\u043e\u0441\u0442\u0440\u043e\u0438\u043c \u043c\u043e\u0434\u0435\u043b\u044c \u043a\u0440\u0438\u0442\u0438\u043a\u0430. \u041f\u043e\u0434\u0430\u0435\u043c \u0441\u0440\u0435\u0434\u0443 \u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043d\u0430\u0433\u0440\u0430\u0434\u0443 action_input = Input(shape=(nb_actions,), name='action_input') observation_input = Input(shape=(1,) + env.observation_space.shape, name='observation_input') flattened_observation = Flatten()(observation_input) x = Concatenate()([action_input, flattened_observation]) x = Dense(8, use_bias=False)(x) x = Activation('relu')(x) x = Dense(5, use_bias=True)(x) x = Activation('relu')(x) x = Dense(1)(x) x = Activation('linear')(x) critic = Model(inputs=[action_input, observation_input], outputs=x) print(critic.summary())  # Keras-RL \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u043a\u043b\u0430\u0441\u0441, rl.memory.SequentialMemory # \u0433\u0434\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \"\u043e\u043f\u044b\u0442\" \u0430\u0433\u0435\u043d\u0442\u0430: memory = SequentialMemory(limit=100000, window_length=1) # \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0437\u0430\u0441\u0442\u0440\u044f\u0442\u044c \u0441 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u043c \u043c\u0438\u043d\u0438\u043c\u0443\u043c\u0435, \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043c\u043e\u0434\u0435\u043b\u0438 \u043f\u043e\u043b\u0435\u0437\u043d\u043e \"\u0432\u0441\u0442\u0440\u044f\u0445\u0438\u0432\u0430\u0442\u044c\" \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u043c \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435\u043c  # \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u041f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u041e\u0440\u043d\u0448\u0442\u0435\u0439\u043d\u0430 \u2013 \u0423\u043b\u0435\u043d\u0431\u0435\u043a\u0430 random_process = OrnsteinUhlenbeckProcess(size=nb_actions, theta=.15, mu=0., sigma=.3) # \u0421\u043e\u0437\u0434\u0430\u0435\u043c agent \u0438\u0437 \u043a\u043b\u0430\u0441\u0441\u0430 DDPGAgent agent = DDPGAgent(nb_actions=nb_actions, actor=actor, critic=critic, critic_action_input=action_input,                   memory=memory, nb_steps_warmup_critic=100, nb_steps_warmup_actor=100,                   random_process=random_process, gamma=.99, target_model_update=1e-3)  agent.compile(Adam(learning_rate=.001, clipnorm=1.), metrics=['mae'])  # \u041e\u0431\u0443\u0447\u0438\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043d\u0430 nb_steps \u0448\u0430\u0433\u0430\u0445,  # nb_max_episode_steps \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0448\u0430\u0433\u043e\u0432 \u0432 \u043e\u0434\u043d\u043e\u043c \u044d\u043f\u0438\u0437\u043e\u0434\u0435 agent.fit(env, nb_steps=100000, visualize=True, verbose=1, nb_max_episode_steps=Epochs)  # \u0422\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c \u043e\u0431\u0443\u0447\u0435\u043d\u0443\u044e \u0441\u0435\u0442\u044c \u043d\u0430 5 \u044d\u043f\u0438\u0437\u043e\u0434\u0430\u0445 agent.test(env, nb_episodes=5, visualize=True, nb_max_episode_steps=Epochs) env.close()<\/code><\/pre>\n<h2>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442<\/h2>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043e\u0431\u0443\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u043d\u0430\u043d\u043e \u0440\u043e\u0431\u043e\u0442\u0430. \u0418\u0437\u043c\u0435\u043d\u0438\u043c \u0434\u043b\u044f \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e\u0441\u0442\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0441\u0440\u0435\u0434\u044b<\/p>\n<pre><code class=\"python\">v0 = 4        # \u043b\u0438\u043d\u0435\u0439\u043d\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c N = 1000      # \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439 Epochs =  500 # \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0448\u0430\u0433\u043e\u0432 L    = 300    # \u0440\u0430\u0437\u043c\u0435\u0440 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 R    = 5      # \u0440\u0430\u0434\u0438\u0443\u0441 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f observation_R = 2*R # \u0420\u0430\u0434\u0438\u0443\u0441 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0441\u043e\u0441\u0435\u0434\u0435\u0439  fig = plt.figure() camera = Camera(fig) random.seed(123) theCure = Cure() observation = theCure.reset()  # \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u043f\u043b\u0430\u0448\u043a\u0430 props = dict(boxstyle='round', facecolor='wheat', alpha=0.5) sum_reward = 0 for i in range(200):     action = np.sum(actor.predict(observation.reshape((1,1,5))))# % (2*np.pi)     observation, reward, done, _ = theCure.step(action)     sum_reward += reward     if done:       print('\u041f\u043e\u0431\u0435\u0434\u0430  \u043d\u0430 \u0448\u0430\u0433\u0435',i, ' \u0437\u0430\u0445\u0432\u0430\u0447\u0435\u043d\u043e ',observation[0]*20,'\u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439. \u041d\u0430\u0433\u0440\u0430\u0434\u0430 ',sum_reward)       break     # \u043f\u043e\u043a\u0430\u0436\u0435\u043c \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439     bacteria_x,bacteria_y = theCure.get_bacteria()     plt.scatter(bacteria_x, bacteria_y, c='red')    #  \u043c\u0435\u0442\u043e\u0434, \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u044e\u0449\u0438\u0439 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0432\u0438\u0434\u0435 \u0442\u043e\u0447\u0435\u043a     # \u043f\u043e\u043a\u0430\u0436\u0435\u043c \u0440\u043e\u0431\u043e\u0442\u0430     x, y, r = theCure.get_position()     plt.scatter(x, y, c='blue')     fig = plt.gcf()     ax = fig.gca()     circle = plt.Circle((x, y), r, color='b', fill=False)     ax.add_patch(circle)      textstr = '\\n'.join((     r'epoch=%d' % (i, ),     r'points=%d' % (reward, ),     ))      ax.text(0.05, 0.95, textstr, transform=ax.transAxes, fontsize=14,       verticalalignment='top', bbox=props)      camera.snap()  print('\u0418\u0442\u043e\u0433\u043e\u0432\u043e\u0435 \u0432\u043e\u0437\u043d\u0430\u0433\u0440\u0430\u0436\u0434\u0435\u043d\u0438\u0435',sum_reward) theCure.close() animation = camera.animate() #animation.save('celluloid_minimal.gif', writer = 'imagemagick') animation<\/code><\/pre>\n<figure class=\"float bordered full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/614\/5ba\/75d\/6145ba75d8d47e3ed8831e26a0d5ef5c.gif\" alt=\"\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f\" title=\"\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f\" width=\"640\" height=\"360\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/614\/5ba\/75d\/6145ba75d8d47e3ed8831e26a0d5ef5c.gif\"\/><figcaption>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f<\/figcaption><\/figure>\n<h2> <\/h2>\n<h2>\u0412\u044b\u0432\u043e\u0434\u044b<\/h2>\n<p>\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442\u00a0\u0434\u0435\u0444\u0438\u0446\u0438\u0442\u00a0\u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438\u00a0\u043f\u043e\u00a0RL\u00a0\u0434\u0430\u0436\u0435\u00a0\u043d\u0430\u00a0\u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c\u00a0\u044f\u0437\u044b\u043a\u0435,\u00a0\u0432\u0430\u043c\u00a0\u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0442\u00a0\u043e\u0441\u043d\u043e\u0432\u044b,\u00a0\u043f\u043e\u043a\u0430\u0436\u0443\u0442\u00a0\u043f\u0430\u0440\u0443\u00a0\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445\u00a0\u0437\u0430\u0434\u0430\u0447\u00a0\u0438\u0437\u00a0\u0430\u0440\u0441\u0435\u043d\u0430\u043b\u0430\u00a0Open\u00a0Gym,\u00a0\u043d\u0430\u00a0\u044d\u0442\u043e\u043c\u00a0&#8212;\u00a0\u0432\u0441\u0435.\u00a0<a href=\"https:\/\/keras-rl.readthedocs.io\/en\/latest\/\" rel=\"noopener noreferrer nofollow\">\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f\u00a0\u043f\u043e\u00a0Keras-RL<\/a>\u00a0\u043d\u0435\u00a0\u0432\u044b\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u00a0\u043d\u0438\u043a\u0430\u043a\u043e\u0439\u00a0\u043a\u0440\u0438\u0442\u0438\u043a\u0438.<\/p>\n<p>\u041e\u0431\u0443\u0447\u0435\u043d\u0438\u0435\u00a0\u0441\u00a0\u043f\u043e\u0434\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u0438\u0435\u043c\u00a0\u0438\u043c\u0435\u0435\u0442\u00a0\u0441\u0432\u043e\u0438\u00a0\u043d\u044e\u0430\u043d\u0441\u044b,\u00a0\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440\u00a0\u0434\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435\u00a0\u043e\u0431\u0443\u0447\u0435\u043d\u0438\u0435\u00a0\u043d\u0430\u00a00.5-1\u00a0\u043c\u043b\u043d.\u00a0\u0448\u0430\u0433\u043e\u0432\u00a0\u043f\u043e\u0445\u043e\u0436\u0435\u00a0\u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u00a0\u043a\u00a0\u043f\u0435\u0440\u0435\u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044e.\u00a0\u0421\u0435\u0442\u044c\u00a0\u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u00a0\u0432\u044b\u0434\u0430\u0432\u0430\u0442\u044c\u00a0\u043a\u0440\u0430\u0439\u043d\u0438\u0435\u00a0\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u00a0-1,1\u00a0\u043d\u0438\u00a0\u043a\u0430\u043a\u00a0\u043d\u0435\u00a0\u0440\u0435\u0430\u0433\u0438\u0440\u0443\u044f\u00a0\u043d\u0430\u00a0\u0441\u0440\u0435\u0434\u0443.\u00a0<\/p>\n<p>\u041f\u0440\u0438\u00a0\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438\u00a0\u0430\u043a\u0442\u0435\u0440\u0430,\u00a0\u0435\u0441\u043b\u0438\u00a0\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442\u00a0\u043d\u0435\u043f\u0440\u0435\u0440\u044b\u0432\u043d\u044b\u0439\u00a0\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0439\u00a0\u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u00a0\u043e\u0440\u0433\u0430\u043d\u043e\u0432\u00a0\u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f,\u00a0\u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439\u00a0\u043d\u0435\u0439\u0440\u043e\u043d\u00a0\u043b\u0443\u0447\u0448\u0435\u00a0\u0437\u0430\u0436\u0430\u0442\u044c\u00a0\u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u044f\u043c\u0438\u00a0sigmoid(0,1)\u00a0\u0438\u043b\u0438\u00a0tanh(-1,+1)\u00a0\u0432\u043c\u0435\u0441\u0442\u043e\u00a0linear.\u00a0\u0417\u0430\u0442\u0435\u043c\u00a0\u0432\u00a0step()\u00a0\u0441\u0440\u0435\u0434\u044b\u00a0\u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c\u00a0\u0434\u043e\u00a0\u0442\u0440\u0435\u0431\u0443\u0435\u043c\u043e\u0433\u043e\u00a0\u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430.<\/p>\n<p>\u041e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u00a0\u043d\u0430\u0434\u043e\u00a0\u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c,\u00a0\u0447\u0442\u043e\u00a0\u043d\u0430\u0431\u043e\u0440\u00a0\u043f\u043e\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0445\u00a0\u0434\u0430\u043d\u043d\u044b\u0445\u00a0\u0434\u043e\u043b\u0436\u0435\u043d\u00a0\u0431\u044b\u0442\u044c\u00a0\u0430\u0434\u0435\u043a\u0432\u0430\u0442\u0435\u043d\u00a0\u0437\u0430\u0434\u0430\u0447\u0435.\u00a0\u041d\u0435\u00a0\u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f\u00a0\u043d\u0430\u0443\u0447\u0438\u0442\u044c\u00a0\u0430\u0433\u0435\u043d\u0442\u0430\u00a0\u0432\u043e\u0436\u0434\u0435\u043d\u0438\u044e\u00a0\u043d\u0435\u00a0\u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044f\u00a0\u0434\u043e\u0440\u043e\u0433\u0438.\u00a0\u0412\u00a0\u043d\u0430\u0448\u0435\u043c\u00a0\u0441\u043b\u0443\u0447\u0430\u0435\u00a0\u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c\u00a0\u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u00a0\u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0438\u00a0\u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044e\u00a0\u0447\u0443\u0442\u044c\u00a0\u0437\u0430\u00a0\u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438\u00a0\u0440\u0430\u0434\u0438\u0443\u0441\u0430\u00a0R.\u00a0\u0411\u0435\u0437\u00a0\u044d\u0442\u043e\u0433\u043e\u00a0\u043d\u0430\u0448\u00a0\u0440\u043e\u0431\u043e\u0442\u00a0\u043f\u0440\u043e\u0441\u0442\u043e\u00a0\u0442\u0430\u0449\u0438\u043b\u0441\u044f\u00a0\u0437\u0430\u00a0\u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439\u00a0\u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0435\u0439\u00a0\u0432\u00a0\u0440\u043e\u0435,\u00a0\u0431\u043e\u044f\u0441\u044c\u00a0\u0431\u044b\u0442\u044c\u00a0\u043d\u0430\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c\u00a0\u0438\u00a0\u043d\u0435\u00a0\u043f\u043e\u043d\u0438\u043c\u0430\u044f\u00a0\u043a\u0430\u043a\u00a0\u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\u00a0\u043d\u0430\u0433\u0440\u0430\u0434\u0443.<\/p>\n<p>\u0427\u0435\u0440\u0435\u0437 \u0442\u0435\u0440\u043d\u0438\u0438 \u043b\u0435\u0436\u0438\u0442 \u043f\u0443\u0442\u044c \u043a \u0437\u0432\u0435\u0437\u0434\u0430\u043c. \u0411\u0443\u0434\u0443 \u0440\u0430\u0434, \u0435\u0441\u043b\u0438 \u043a\u043e\u043c\u0443-\u0442\u043e \u043f\u043e\u043c\u043e\u0433 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0432 \u044d\u0442\u043e\u0439 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0435\u0439\u0448\u0435\u0439 \u0442\u0435\u043c\u0435.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/586474\/\"> https:\/\/habr.com\/ru\/articles\/586474\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h2>\u041f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0437\u0430\u0434\u0430\u0447\u0438<\/h2>\n<p>\u041e\u0431\u0443\u0447\u0435\u043d\u0438\u0435 \u0441 \u043f\u043e\u0434\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u0438\u0435\u043c \u043c\u043e\u043b\u043e\u0434\u0430\u044f \u0438 \u0431\u0443\u0440\u043d\u043e \u0440\u0430\u0441\u0442\u0443\u0449\u0430\u044f \u0434\u0438\u0441\u0446\u0438\u043f\u043b\u0438\u043d\u0430. \u042d\u0442\u043e \u043e\u0431\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u043e \u043f\u0440\u0438\u0432\u0435\u043b\u043e \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e\u0431 \u044d\u0442\u043e\u043c \u043c\u0430\u043b\u043e \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c \u0438 \u043f\u043e\u0447\u0442\u0438 \u043d\u0435\u0442 \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0435. \u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e, \u0435\u0441\u043b\u0438 \u0434\u0435\u043b\u043e \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043d\u043e-\u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430, \u0438 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0437\u0430\u0434\u0430\u0447 \u043d\u0435 \u0438\u0437 \u0430\u0440\u0441\u0435\u043d\u0430\u043b\u0430 <em>Open Gym<\/em>. \u0421\u0442\u0430\u043b\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u043a\u0430\u043a \u0440\u0435\u0448\u0430\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438 RL \u0432 <strong>\u0434\u0440\u0443\u0433\u0438\u0445 <\/strong>\u0441\u0440\u0435\u0434\u0430\u0445.<\/p>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e \u0432\u0430\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043a\u0430\u043a \u044f \u043d\u0430\u0434\u0435\u044e\u0441\u044c, \u0443\u0431\u0435\u0440\u0435\u0436\u0435\u0442 \u0432\u0430\u0441 \u043e\u0442 \u0447\u0430\u0441\u0442\u0438 \u0448\u0438\u0448\u0435\u043a \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0449\u0438\u0445\u0441\u044f \u043d\u0430 \u044d\u0442\u043e\u043c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u043c \u043f\u0443\u0442\u0438.<\/p>\n<p>\u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c \u0437\u0430\u0434\u0430\u0447\u0443, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043d\u0430\u043d\u043e \u0440\u043e\u0431\u043e\u0442 \u0441 \u0430\u043d\u0442\u0438\u0431\u0438\u043e\u0442\u0438\u043a\u043e\u043c \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u0434\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u043a \u0441\u043a\u043e\u043f\u043b\u0435\u043d\u0438\u044e \u043f\u0430\u0442\u043e\u0433\u0435\u043d\u043d\u044b\u0445 \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439 \u0434\u043b\u044f \u0438\u0445 \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u043c Reinforsment Learning \u043e\u0442 Keras \u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0434\u043b\u044f \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438.<\/p>\n<pre><code class=\"python\">!pip install keras-rl2 !pip install celluloid<\/code><\/pre>\n<pre><code class=\"python\"># \u0411\u0430\u0437\u043e\u0432\u044b\u0435 \u041c\u043e\u0434\u0443\u043b\u0438 import time    # \u043c\u043e\u0434\u0443\u043b\u044c \u0434\u043b\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0441\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c\u0438 \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0438\u0441\u0442\u0438\u043a\u0430\u043c\u0438 import random import numpy as np  # \u041c\u043e\u0434\u0443\u043b\u0438 Keras from tensorflow.keras.models import Sequential, Model from tensorflow.keras.layers import Dense, Activation, Flatten, Input, Concatenate from tensorflow.keras.optimizers import Adam  # \u041c\u043e\u0434\u0443\u043b\u0438 Keras-RL2 import rl.core as krl from rl.agents import DDPGAgent from rl.memory import SequentialMemory from rl.random import OrnsteinUhlenbeckProcess  # \u041c\u043e\u0434\u0443\u043b\u0438 \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 from celluloid import Camera import matplotlib.pyplot as plt      from matplotlib import rc rc('animation', html='jshtml') %matplotlib inline<\/code><\/pre>\n<h2>\u0421\u0440\u0435\u0434\u0430<\/h2>\n<p>\u0414\u043b\u044f \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u0441 \u043f\u043e\u0434\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u0438\u0435\u043c \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0441\u0440\u0435\u0434\u0430 \u0438 \u0430\u0433\u0435\u043d\u0442. <\/p>\n<p>\u0421\u0440\u0435\u0434\u043e\u0439 \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0431\u0443\u0434\u0435\u0442 \u043c\u0438\u0433\u0440\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u0432 \u0442\u043a\u0430\u043d\u044f\u0445 \u043f\u0430\u0442\u043e\u0433\u0435\u043d\u044b. \u0418\u0445 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0440\u043e\u0435\u0432\u043e\u043c\u0443 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044e.<\/p>\n<p>\u0420\u043e\u0435\u0432\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u043e \u043c\u043e\u0434\u0435\u043b\u044c\u044e \u0412\u0438\u0447\u0435\u043a\u0430 (1995 \u0433.).\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u044d\u0442\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043c\u043e\u0436\u043d\u043e \u0438\u043c\u0438\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043a\u043e\u043f\u043b\u0435\u043d\u0438\u044f \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439, \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0441\u0442\u0430\u0438 \u043f\u0442\u0438\u0446 \u0438\u043b\u0438 \u043a\u043e\u0441\u044f\u043a\u0430 \u0440\u044b\u0431, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u043a\u0430\u043a \u0438\u0437 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u043f\u0440\u0430\u0432\u0438\u043b \u043f\u043e\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u0430\u043c\u043e \u0443\u043f\u043e\u0440\u044f\u0434\u043e\u0447\u0435\u043d\u043d\u044b\u0435 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0412\u043e\u0437\u044c\u043c\u0435\u043c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u0438\u0437 \u0441\u0442\u0430\u0442\u044c\u0438\u00a0<a href=\"https:\/\/nuancesprog.ru\/p\/11626\/\" rel=\"noopener noreferrer nofollow\">\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0439 \u043c\u0430\u0442\u0435\u0440\u0438\u0438 \u043d\u0430 Python<\/a>. \u0418 \u043f\u0435\u0440\u0435\u043f\u0438\u0448\u0435\u043c \u0435\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043d\u043e-\u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434. \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0432\u044b \u0443\u0436\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u044b \u0441 \u041e\u041e\u041f \u0434\u043b\u044f Python.<\/p>\n<pre><code class=\"python\"># \u0418\u043c\u0438\u0442\u0430\u0446\u0438\u044f \u0440\u043e\u0435\u0432\u043e\u0433\u043e \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f class Colony:   # \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0447\u0430\u0441\u0442\u0438\u0446\u044b    x : np.ndarray   y : np.ndarray   # \u0443\u0433\u043e\u043b \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0447\u0430\u0441\u0442\u0438\u0446\u044b   theta : np.ndarray   # \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0447\u0430\u0441\u0442\u0438\u0446\u044b \u043f\u043e \u043e\u0441\u044f\u043c   vx : np.ndarray   vy : np.ndarray    # \u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440   def __init__(self,N):     self.reset(N)    # \u0440\u0430\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 N \u0447\u0430\u0441\u0442\u0438\u0446 \u043d\u0430 \u043f\u043b\u043e\u0449\u0430\u0434\u043a\u0435 LxL   def reset(self,N):     # \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0447\u0430\u0441\u0442\u0438\u0446      self.x = np.random.rand(N,1)*L     self.y = np.random.rand(N,1)*L     # \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0438 \u043e\u0441\u0435\u0432\u044b\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0447\u0430\u0441\u0442\u0438\u0446 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e      # \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u0439 \u043b\u0438\u043d\u0435\u0439\u043d\u043e\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 v0     self.theta = 2 * np.pi * np.random.rand(N,1)     self.vx = v0 * np.cos(self.theta)     self.vy = v0 * np.sin(self.theta)   # \u0428\u0430\u0433 \u0438\u043c\u0438\u0442\u0430\u0446\u0438\u0438   def step(self):     # \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435     self.x += self.vx*dt     self.y += self.vy*dt     # \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u043d\u044b\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u0439     self.x = self.x % L     self.y = self.y % L     # \u043d\u0430\u0439\u0442\u0438 \u0441\u0440\u0435\u0434\u043d\u0438\u0439 \u0443\u0433\u043e\u043b \u0441\u043e\u0441\u0435\u0434\u0435\u0439 \u0432 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0435 R     mean_theta = self.theta     for b in range(N):         neighbors = (self.x-self.x[b])**2+(self.y-self.y[b])**2 &lt; R**2         sx = np.sum(np.cos(self.theta[neighbors]))         sy = np.sum(np.sin(self.theta[neighbors]))         mean_theta[b] = np.arctan2(sy, sx)     # \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0433\u043e \u043e\u0442\u043a\u043b\u043e\u043d\u0435\u043d\u0438\u044f     self.theta = mean_theta + eta*(np.random.rand(N,1)-0.5)     # \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438     self.vx = v0 * np.cos(self.theta)     self.vy = v0 * np.sin(self.theta)     return self.theta    # \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0447\u0430\u0441\u0442\u0438\u0446 \u0432 \u0432\u043d\u0443\u0442\u0440\u0438 \u0440\u0430\u0434\u0438\u0443\u0441\u0430 r \u043e\u0442 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 x,y   def observe(self,x,y,r):     return (self.x-x)**2+(self.y-y)**2 &lt; r**2   # \u0412\u044b\u0432\u0435\u0441\u0442\u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0447\u0430\u0441\u0442\u0438\u0446\u044b i   def print(self,i):     return print(self.x[i],self.y[i])   # \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0447\u0430\u0441\u0442\u0438\u0446   def get_bacteria(self):     return self.x, self.y    # \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0439 \u0447\u0430\u0441\u0442\u0438\u0446   def get_theta(self):     return self.theta <\/code><\/pre>\n<p>\u041e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u043f\u043e\u0441\u043b\u0443\u0436\u0438\u0442 \u043d\u0430\u043c \u0434\u043b\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0441\u0440\u0435\u0434\u044b\u00a0<em>state<\/em>. \u041d\u0435 \u043f\u0443\u0442\u0430\u0439\u0442\u0435\u00a0<em>observation<\/em>\u00a0\u0438\u00a0<em>state<\/em>. \u041d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u043c\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435\u00a0<strong><em>observation<\/em><\/strong>, \u044d\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e, \u0447\u0442\u043e \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u0442 \u0430\u0433\u0435\u043d\u0442. \u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c\u00a0<em>state<\/em>\u00a0\u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u0432\u0441\u044f \u0441\u0440\u0435\u0434\u0430: \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0432\u0441\u0435\u0445 \u043d\u0430\u0448\u0438\u0445 \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439.<\/p>\n<p>\u0414\u043b\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0432 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u043a\u043b\u0430\u0441\u0441\u0430\u00a0<em>action_space<\/em>\u00a0\u0438\u00a0<em>observation_space<\/em>\u00a0\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u00a0<em>action<\/em>\u00a0\u0430\u0433\u0435\u043d\u0442\u0430 \u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0440\u0435\u0434\u044b\u00a0<em>observation<\/em>.<\/p>\n<p>\u0418\u0445 \u043d\u0430\u0434\u043e \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u043e\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 rl.Space. \u0414\u043b\u044f action_space \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b:<\/p>\n<ul>\n<li>\n<p><strong>sample()<\/strong>\u00a0&#8212; \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0435 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0447\u0438\u0441\u043b\u043e \u0438\u0437 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430 [-1,1)<\/p>\n<\/li>\n<li>\n<p><strong>contains(x)<\/strong>\u00a0&#8212; \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 x \u043d\u0430 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u044c.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0435 shape \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0444\u043e\u0440\u043c\u0443 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439<\/p>\n<pre><code class=\"python\"># action - \u0441\u043a\u0430\u043b\u044f\u0440 \u043e\u0442 -1 \u0434\u043e 1 class actionSpace(krl.Space):   def __init__(self):     self.shape = (1,)   def sample(self, seed=None):     if seed: random.seed(seed)     return random.triangular(-1,1)   def contains(self, x):     return  abs(x) &lt;= 1  # observation - \u043c\u0430\u0441\u0441\u0438\u0432  # \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u043d\u0435 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c. class observationSpace(krl.Space):   def __init__(self):     self.shape = (5,) #   def sample(self, seed=None): pass   def contains(self, x): pass<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0440\u0435\u0434\u0443 \u043d\u0430\u043c \u043d\u0430\u0434\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u044f \u0435\u0435 \u0438\u0437 \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 \u0441\u0440\u0435\u0434\u044b\u00a0<em>rl.Env<\/em>\u00a0\u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u043e\u0439 \u043a\u0435\u0440\u0430\u0441. \u042d\u0442\u043e \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441, \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 \u0437\u0430\u0434\u0443\u043c\u0430\u043d\u043d\u043e\u0439 \u0441\u0440\u0435\u0434\u043e\u0439 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0435\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u044b:<\/p>\n<ul>\n<li>\n<p><strong>reset()<\/strong>\u00a0&#8212; &#171;\u0441\u043e\u0442\u0432\u043e\u0440\u0435\u043d\u0438\u0435 \u043c\u0438\u0440\u0430&#187;<\/p>\n<\/li>\n<li>\n<p><strong>step(action)<\/strong>\u00a0&#8212; \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043c\u0438\u0440\u0430 \u043d\u0430 \u0448\u0430\u0433\u0435 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 action<\/p>\n<\/li>\n<li>\n<p><strong>render()<\/strong>\u00a0&#8212; \u0432\u044b\u0432\u043e\u0434 \u043b\u044e\u0431\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043f\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044e \u043c\u0438\u0440\u0430 \u043d\u0430 \u0434\u0430\u043d\u043d\u043e\u043c \u0448\u0430\u0433\u0435.<\/p>\n<\/li>\n<li>\n<p><strong>close()<\/strong>\u00a0&#8212; \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 \u043a\u043b\u0430\u0441\u0441\u0430<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u043a\u043b\u0430\u0441\u0441\u0435 \u0441\u0440\u0435\u0434\u044b \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u00a0<em>state<\/em>, \u043d\u0430\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u0435\u00a0<em>observation<\/em>, \u043d\u0430\u0433\u0440\u0430\u0434\u0443\u00a0<em>reward<\/em>.<\/p>\n<p>\u0412\u00a0<em>observation<\/em>\u00a0\u043f\u043e\u0434\u0430\u0434\u0438\u043c 5 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445:<\/p>\n<ol>\n<li>\n<p>\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e &#171;\u0437\u0430\u0445\u0432\u0430\u0447\u0435\u043d\u043d\u044b\u0445&#187; \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439 \u0432\u043d\u0443\u0442\u0440\u0438 \u0440\u0430\u0434\u0438\u0443\u0441\u0430 R<\/p>\n<\/li>\n<li>\n<p>\u0421\u0440\u0435\u0434\u043d\u0438\u0439 \u0443\u0433\u043e\u043b \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439 \u0432\u043d\u0443\u0442\u0440\u0438 R<\/p>\n<\/li>\n<li>\n<p>\u0423\u0433\u043e\u043b \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0430 \u0446\u0435\u043d\u0442\u0440 \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439 \u0432\u043d\u0443\u0442\u0440\u0438 R<\/p>\n<\/li>\n<li>\n<p>\u0423\u0433\u043e\u043b \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0430 \u0446\u0435\u043d\u0442\u0440 \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u0440\u0443\u0433\u0430 R-1.5R<\/p>\n<\/li>\n<li>\n<p>\u0422\u0435\u043a\u0443\u0449\u0438\u0439 \u0443\u0433\u043e\u043b \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0430\u043d\u043e \u0440\u043e\u0431\u043e\u0442\u0430<\/p>\n<p>\u041d\u0430\u0433\u0440\u0430\u0434\u0430 &#8212; \u0442\u043e\u0447\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432\u0430\u0448\u0435\u0433\u043e \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f. \u041d\u0430\u0433\u0440\u0430\u0434\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0435. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0441\u0442\u0440\u043e\u0433\u043e \u0448\u0442\u0440\u0430\u0444\u043e\u0432\u0430\u0442\u044c \u0437\u0430 \u043f\u043e\u0442\u0435\u0440\u044e \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439, \u0442\u0435\u043c \u0441\u0442\u0440\u043e\u0436\u0435 \u0447\u0435\u043c \u0438\u0445 \u043c\u0435\u043d\u044c\u0448\u0435 \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 R. \u0422\u0430\u043a \u0436\u0435, \u0440\u0435\u0448\u0438\u043c \u043f\u043e\u043e\u0449\u0440\u044f\u0442\u044c \u0437\u0430 \u043f\u0440\u0438\u043e\u0431\u0440\u0435\u0442\u0435\u043d\u0438\u0435 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0442\u043e\u0447\u0435\u043a.<\/p>\n<p>\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0435\u043c,- \u0431\u0443\u0434\u0435\u0442 \u0443\u0433\u043e\u043b \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u043d\u0430\u043d\u043e \u0440\u043e\u0431\u043e\u0442\u0430. \u0412\u0441\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0434\u0435\u043b\u0435\u043d\u0438\u0435\u043c \u043d\u0430\u00a0<em>Pi<\/em>.<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"python\"># \u043d\u0430\u0448\u0430 \"\u0447\u0430\u0448\u0435\u0447\u043a\u0430 \u041f\u0435\u0442\u0440\u0438\" class Cure(krl.Env):   # \u0438\u043c\u0438\u0442\u0438\u0440\u0443\u0435\u043c\u0430\u044f \u043a\u043e\u043b\u043e\u043d\u0438\u044f   bacteria : Colony   # \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430\u043d\u043e \u0440\u043e\u0431\u043e\u0442\u0430   x: float   y: float   theta: float  # \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430\u043d\u043e \u0440\u043e\u0431\u043e\u0442\u0430   R: float  # \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439 \u043d\u0430\u043d\u043e \u0440\u043e\u0431\u043e\u0442\u043e\u043c   n_bacteria : int  # \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0432\u0438\u0434\u0438\u043c\u044b\u0445 \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439 \u0434\u043b\u044f rewarda   # \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440   def __init__(self):     self.bacteria = Colony(N)     self.reward_range = (-1,1) #(-np.inf, np.inf)     self.action_space = actionSpace()     self.observation_space = observationSpace()     self.R = observation_R     self.reset()    #  \u0424\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u0435\u043a\u0442\u043e\u0440\u0430 \u043e\u0431\u0437\u043e\u0440\u0430 observation.   #  \u0422\u043e \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 R \u043e\u0442 \u0440\u043e\u0431\u043e\u0442\u0430.    def observe_area(self):     # \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0441\u043e\u0441\u0435\u0434\u0435\u0439 \u0432 \u0440\u0430\u0434\u0438\u0443\u0441\u0435 R     observe_bacteria = self.bacteria.observe(self.x,self.y,self.R)     # \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0441\u043e\u0441\u0435\u0434\u0435\u0439 \u0432 \u0440\u0430\u0434\u0438\u0443\u0441\u0435 R*1.5     observe_far_bacteria = self.bacteria.observe(self.x,self.y,self.R*1.5)     observe_far_bacteria=np.array(np.bitwise_and(observe_far_bacteria,np.invert (observe_bacteria)))      observation = np.zeros(5)     # \u043f\u043e\u0434\u0430\u0434\u0438\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043e\u0441\u0435\u0434\u0435\u0439         n_bacteria = np.sum(observe_bacteria)     observation[0] = n_bacteria\/20      # \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0435\u043c \u0438 \u043f\u043e\u0434\u0430\u0434\u0438\u043c \u0441\u0440\u0435\u0434\u043d\u0435\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0439 \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u0445 \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439     sx = np.sum(np.cos(self.bacteria.theta[observe_bacteria]))     sy = np.sum(np.sin(self.bacteria.theta[observe_bacteria]))     observation[1] = np.arctan2(sy, sx)\/np.pi     # \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0435\u043c \u0438 \u043f\u043e\u0434\u0430\u0434\u0438\u043c \u0441\u0440\u0435\u0434\u043d\u0435\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0442 \u0440\u043e\u0431\u043e\u0442\u0430 \u0434\u043e \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u044b\u0445 \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439     sx = np.sum(self.bacteria.x[observe_bacteria]-self.x)     sy = np.sum(self.bacteria.y[observe_bacteria]-self.y)     observation[2] = np.arctan2(sy, sx)\/np.pi     # \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0435\u043c \u0438 \u043f\u043e\u0434\u0430\u0434\u0438\u043c \u0441\u0440\u0435\u0434\u043d\u0435\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0442 \u0440\u043e\u0431\u043e\u0442\u0430 \u0434\u043e \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u044b\u0445 \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439     sx = np.sum(self.bacteria.x[observe_far_bacteria]-self.x)     sy = np.sum(self.bacteria.y[observe_far_bacteria]-self.y)     observation[3] = np.arctan2(sy, sx)\/np.pi     if n_bacteria:       observation[4]=self.theta\/np.pi # \u043f\u043e\u0434\u0430\u0434\u0438\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430\u043d\u043e\u0440\u043e\u0431\u043e\u0442\u0430     return np.sum(observe_bacteria), observation    # \u0441\u0442\u0430\u0440\u0442 \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u0438   def reset(self):     self.bacteria.reset(N)     self.x = .5*L     self.y = .5*L     self.theta = actionSpace().sample()     self.n_bacteria , observation = self.observe_area()     return observation        # \u0448\u0430\u0433 \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u0438   def step(self,action):     action = action * 3.2#np.pi     #  \u0414\u043b\u044f \u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043f\u0440\u0438 \u043f\u043e\u043f\u0430\u0434\u0430\u043d\u0438\u0438 \u043d\u0430 \"\u0447\u0438\u0441\u0442\u0443\u044e \u0432\u043e\u0434\u0443\"      #  \u043f\u0440\u043e\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u044e \u043d\u0435 \u0432\u044b\u043f\u0443\u0441\u043a\u0430\u044f \u0435\u0435 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u0435\u0442\u0438     while True:       # \u0448\u0430\u0433 \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u0438 \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439       self.bacteria.step()       # \u0448\u0430\u0433 \u0440\u043e\u0431\u043e\u0442\u0430       self.theta = np.sum(action) #% (2*np.pi)       self.x = self.x + dt*v0 * np.cos(self.theta)       self.y = self.y + dt*v0 * np.sin(self.theta)       self.x = self.x  % L       self.y = self.y  % L       # \u043e\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435       nBacteria, observation = self.observe_area()       if np.sum(observation)!=0: break       if self.n_bacteria > 0: break      delta = nBacteria - self.n_bacteria     if delta&lt;0:       reward = 50 * delta\/self.n_bacteria     elif delta>0 and self.n_bacteria:       reward = 1+delta     elif nBacteria>0:       reward = 1             elif nBacteria == 0:       reward = 0     else:        reward = nBacteria     done = nBacteria > N\/7     self.n_bacteria = nBacteria     return observation, reward, done, {}    # \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0440\u043e\u0431\u043e\u0442\u0430   def get_position(self):     return self.x, self.y, self.R   # \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0432\u0441\u0435\u0445 \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439   def get_bacteria(self):     return self.bacteria.get_bacteria()   # \u043e\u0442\u0440\u0430\u0437\u0438\u0442\u044c \u043e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e      def render(self, mode='human', close=False):     #print(self.n_bacteria)     pass   # \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u044e   def close(self): pass     <\/code><\/pre>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u044d\u0442\u0430\u043f\u0435, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0441\u0440\u0435\u0434\u044b \u0438 \u043f\u0440\u043e\u0438\u0433\u0440\u0430\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0435 \u044d\u043f\u0438\u0437\u043e\u0434\u044b. <\/p>\n<figure class=\"float full-width\"><figcaption>\u041f\u0440\u043e\u0438\u0433\u0440\u044b\u0448 \u044d\u043f\u0438\u0437\u043e\u0434\u043e\u0432<\/figcaption><\/figure>\n<p>\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 \u044d\u043f\u0438\u0437\u043e\u0434\u043e\u0432 \u0434\u0430\u0441\u0442 \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0441 \u043a\u0430\u043a\u0438\u043c \u0440\u0430\u0437\u043d\u043e\u043e\u0431\u0440\u0430\u0437\u0438\u0435\u043c \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0439 \u0443\u0441\u043f\u0435\u0432\u0430\u0435\u0442 \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u0442\u044c\u0441\u044f \u043d\u0430\u0448 \u0440\u043e\u0431\u043e\u0442. \u0412 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u044d\u0442\u043e\u0433\u043e, \u0440\u0435\u0433\u0443\u043b\u0438\u0440\u0443\u0435\u043c: \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0431\u0430\u043a\u0442\u0435\u0440\u0438\u0439; \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u043b\u043e\u0449\u0430\u0434\u043a\u0438; \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u044d\u043f\u043e\u0445.<\/p>\n<p>\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u044d\u0442\u043e<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-412947","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/412947","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=412947"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/412947\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=412947"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=412947"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=412947"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}