def _setup(self) -> None: if population.count() == 0: while population.count() < seq.minimum_bounding_n( config.P_VALUE / max(1, population.count())): self._logger.info("Создается базовый организм:") org = population.create_new_organism() self._logger.info(f"{org}\n") self._scale = int(population.count()**0.5)
def evolve(self, portfolio: Portfolio) -> None: """Осуществляет эволюции. При необходимости создается начальная популяция из организмов по умолчанию. """ self._setup() tickers = tuple(portfolio.index[:-2]) end = portfolio.date scale = 1.0 step = 0 while True: step += 1 print(f"***{end.date()}: Шаг эволюции — {step}***") population.print_stat() print(f"Фактор - {scale:.2%}\n") parent = population.get_parent() print("Переоцениваю родителя:") if _eval_and_print(parent, tickers, end) is None: scale *= SCALE_DOWN continue child = parent.make_child(scale) print("Потомок:") if _eval_and_print(child, tickers, end) is None: scale *= SCALE_DOWN continue if population.count() > self._max_population: _kill_weakest(child)
def test_count(): assert population.count() == 4 org1 = population.Organism() org1._doc.save() assert population.count() == 5 org2 = population.Organism() org2._doc.save() assert population.count() == 6 org1.die() assert population.count() == 5 org2.die() assert population.count() == 4
def _test_diff(diff: list[float]) -> tuple[float, float, float]: """Последовательный тест на медианную разницу с учетом множественного тестирования. Тестирование одностороннее, поэтому p-value нужно умножить на 2, но проводится 2 раза. """ _, upper = seq.median_conf_bound(diff, config.P_VALUE / population.count()) return float(np.median(diff)), upper, np.max(diff)
def evolve(self, portfolio: Portfolio) -> NoReturn: """Осуществляет одну эпоху эволюции. При необходимости создается начальная популяция из организмов по умолчанию. """ tickers = tuple(portfolio.index[:-2]) end = portfolio.date self._setup() count = population.count() for step, parent in enumerate(population.get_all_organisms(), 1): print(f"***{end.date()}: Шаг эпохи - {step}/{count}***") population.print_stat() print() print("Родитель:") parent_fitness = self._eval_and_print(parent, tickers, end) if parent_fitness is None: continue child = parent.make_child() print("Потомок:") child_fitness = self._eval_and_print(child, tickers, end) if child_fitness is None: continue if population.count() <= self._max_population: continue weakest = parent if parent_fitness > child_fitness: weakest = child weakest = weakest.find_weaker() print("Более слабый и наиболее медленный - удаляю:") self._eval_and_print(weakest, tickers, end) weakest.die()
def _eval_exiting(self, portfolio: Portfolio) -> None: """Оценивает существующих.""" tickers = tuple(portfolio.index[:-2]) end = portfolio.date count = population.count() for step, parent in enumerate(population.get_all_organisms(), 1): print(f"***{end.date()}: Шаг переоценки существующих организмов - {step}/{count}***") population.print_stat() print() print("Родитель:") parent_fitness = self._eval_and_print(parent, tickers, end) if parent_fitness is None: continue
def _setup(self) -> NoReturn: """Создает популяцию из организмов по умолчанию. Если организмов меньше 4 - минимальное количество для осуществления эволюции. """ count = population.count() print(f"Имеется {count} организмов из {self._max_population}") print() if count < 4: for i in range(1, self._max_population - count + 1): print(f"Создаю базовые генотипы - {i}/{self._max_population - count}") organism = population.create_new_organism() print(organism) print()
def evolve(self, portfolio: Portfolio) -> NoReturn: """Осуществляет одну эпоху эволюции. При необходимости создается начальная популяция из организмов по умолчанию. """ tickers = tuple(portfolio.index[:-2]) end = portfolio.date self._setup() self._eval_exiting(portfolio) count = population.count() factor = MUTATION_FACTOR for step, parent in enumerate(population.get_all_organisms(), 1): print(f"***{end.date()}: Шаг размножения - {step}/{count}***") population.print_stat() print(f"Фактор - {factor:.2%}") print() child = parent.make_child(factor) print("Потомок:") child_fitness = self._eval_and_print(child, tickers, end) if child_fitness is None: factor *= MUTATION_FACTOR continue if population.count() <= self._max_population: continue weakest = child.find_weaker() print("Наиболее слабый - удаляю:") self._eval_and_print(weakest, tickers, end) weakest.die()
def __init__(self): """Инициализирует необходимые параметры.""" self._tickers = None self._end = None self._logger = logging.getLogger() self._scale = int(population.count()**0.5)
def _n_test(scores: int = -1) -> int: return max(population.count(), scores + 1)
if margin[0] - margin[1] < 0: self._logger.info("Медленный не размножается...\n") return None prey = hunter.make_child(1 / max(1, self._scale)) self._logger.info(f"Потомок:") if (margin := self._eval_organism(prey)) is None: return None if margin[0] < 0: self._scale += 1 return None self._scale = max(int(population.count()**0.5), self._scale - 1) if margin[0] - margin[1] < 0: return None return None def _eval_organism( self, organism: population.Organism) -> Optional[tuple[float, float]]: """Оценка организмов. - Если организм уже оценен для данной даты, то он не оценивается. - Если организм старый, то оценивается один раз. - Если организм новый, то он оценивается для определенного количества дат из истории. """
def _n_test(self) -> int: return max(population.count(), seq.minimum_bounding_n(config.P_VALUE), self._scale)