#python #multiprocessing #python-multiprocessing #genetic-algorithm
Вопрос:
Я разрабатывал генетический алгоритм для решения простых уровней 2D-платформера. Теперь я хочу добавить многопроцессорную обработку для параллельного выполнения «обновления» моей совокупности, но мне не удалось заставить ее работать, так как все рабочие примеры, которые я нашел, относятся к простым массивам, даже с общей памятью, и мне нужно работать с вложенными объектами и общей памятью.
Прямо сейчас я пытаюсь выполнить следующий код:
# divide players for processes
splits = np.array_split(groups.players_group, settings.PROCESSES)
# create processes
processes = []
for i in range(settings.PROCESSES):
p = mp.Process(target=update_players, args=(splits[i],))
processes.append(p)
processes[i].start()
# join processes (wait for 'em to finish)
for p in processes:
p.join()
Теперь ошибки не были ясны, так как теперь у них просто возникают проблемы с поиском объектов (в журналах говорится, что есть пустые объекты, которые не обладают каким-либо необходимым свойством для процесса обновления, хотя на самом деле они должны его иметь. Поэтому я начинаю верить, что проблема связана с общей памятью, которую я не знаю, как применить к объектам python).
[ПРАВИТЬ]
Я попытался обернуть свои списки объектов с multiprocessing.Array()
помощью , но это приводит к следующей ошибке:
Ошибка типа: неподдерживаемые типы операндов для*: «тип» и «int»
Также… вот функция «обновить игроков» :
def update_players(players, ret_queue):
for p in players:
p.update()
ret_queue.put(players)
и, как вы можете видеть , он звонит Player.Update()
, что безумно долго, но вот он на случай, если вы захотите его проверить:
def update(self):
if not self.is_dead and not self.reached_goal and not self.finished:
# act according to brain if necessary
if self.is_ai:
# reset movements
self.releaseLeft()
self.releaseRight()
if self.brain_step >= len(self.brain.instructions):
if not self.reached_goal and not self.isMoving():
self.finished = True
else:
self.executeNextBrainStep()
self.rect.y = self.y_spd
self.y_spd = self.gravity
# check if player is colliding with floor
for tile in groups.floor_tiles:
if helpers.rectsColliding(self.rect, tile.rect):
# check vertical collision
if self.rect.getCenterY() < tile.rect.y: # from top
self.y_spd = 0
self.rect.y = tile.rect.y - self.rect.height 1
self.is_jumping = False
# from bottom
elif self.rect.getCenterY() > (tile.rect.y tile.rect.height):
self.y_spd = 0
self.rect.y = tile.rect.y tile.rect.height
# check horizontal collision
# should be within same vertical space
if self.rect.getCenterY() >= (tile.rect.getCenterY() - tile.rect.height/3):
if self.rect.getCenterY() <= (tile.rect.getCenterY() tile.rect.height/3):
# now we can check the horizontal collision
if self.rect.getCenterX() < tile.rect.x: # from left
self.right = 0
self.rect.x = tile.rect.x - self.rect.width
# from right
elif self.rect.getCenterX() > (tile.rect.x tile.rect.width):
self.left = 0
self.rect.x = tile.rect.x tile.rect.width
self.dir = (self.right - self.left)
self.rect.x = self.dir * self.walk_spd
# check if dead
if self.rect.x > settings.SCR_W or (self.rect.x self.rect.width) < 0:
self.is_dead = True
self.finished = True
if self.rect.y > settings.SCR_H or (self.rect.y self.rect.height) < 0:
self.is_dead = True
self.finished = True
# if optimizing, check if should stop
if settings.OPTIMIZATION_FITNESS:
self_dist = helpers.dist_modular(self.rect.x, settings.goal.rect.x, self.rect.y, settings.goal.rect.y)
best_dist = helpers.dist_modular(settings.BEST_X, settings.goal.rect.x, settings.BEST_Y, settings.goal.rect.y)
if self_dist < best_dist:
self.finished = True
self.reached_goal = True
# check if reached goal
if helpers.objectsColliding(self, settings.goal):
self.reached_goal = True
self.finished = True
И на случай, если кто-нибудь из вас захочет проверить репо, вот оно: https://github.com/santyarellano/GeneticLevelTester
Комментарии:
1. вы можете поделиться функцией update_players?
2. да, я добавлю это в главный вопрос
3. У update_players есть два символа, которые вы передаете только одному.
4. да… это было то, что я пробовал, но это не то :/