Сделайте случайное движение пикселей более эффективным - PullRequest
0 голосов
/ 21 мая 2018

Мой код использует три случайных числа и несколько операторов if для случайного перемещения пикселя.Используя cProfiler, получается, что эта функция довольно неэффективна.

s = self.surrounding()
surroundingBool = [False if i == None else True for i in s]

r1 = random.random()
r2 = random.random()
r3 = random.random()

if r1 <= 0.333:
    if r3 < 0.5 and not surroundingBool[4]: self.x += 1
    elif not surroundingBool[3]: self.x -= 1
elif r1 <= 0.666:
    if r3 < 0.5 and not surroundingBool[6]: self.y += 1
    elif not surroundingBool[1]: self.y -= 1
else:
    if r2 < 0.25 and not surroundingBool[7]:
        self.x += 1
        self.y += 1
    elif r2 < 0.5 and not surroundingBool[2]:
        self.x += 1
        self.y -= 1
    elif r2 < 0.75 and not surroundingBool[5]:
        self.x -= 1
        self.y += 1
    elif not surroundingBool[0]:
        self.x -= 1
        self.y -= 1

self.x %= width
self.y %= height
    self.pos = self.y * width + self.x

Надеюсь, это довольно очевидно, но я могу предоставить контекст по мере необходимости.Как я могу сделать это, если еще операторы быстрее или эффективнее?

Полный код можно найти здесь , если необходимо.

1 Ответ

0 голосов
/ 21 мая 2018

Вот другой подход, который вы можете отклонить, если считаете, что он отличается от вашего метода перемещения пикселей.Поскольку в двумерном массиве пикселей имеется максимум восемь возможных движений к соседним пикселям, вы можете определить постоянную list движений и сопоставить их с индексом, который относится к пикселю, полученному в результате указанного движения.

Исходя из моей интерпретации вашего кода, это то, что вы можете определить в методе __init__ вашего pixel класса.

Настройка:

changes_1d = (-1, 0, 1)
changes_2d = [(i,j) for j in changes_1d for i in changes_1d if i or j]
self.movements = tuple(enumerate(changes_2d))  # Assign pixel index to each movement

Содержимое self.movements:

0 (-1, -1)
1 (0, -1)
2 (1, -1)
3 (-1, 0)
4 (1, 0)
5 (-1, 1)
6 (0, 1)
7 (1, 1)

Зачем настраивать это?Теперь мы можем использовать random.choice() для быстрого выбора случайного движения двумерного пикселя, и мы можем проверить, является ли этот ход действительным, используя индекс, возвращаемый вместе с парой движений (dx, dy):

def move(self):
    s = self.surrounding()
    surroundingBool = [i is not None for i in s]

    pixel, movement = random.choice(self.movements)

    if surroundingBool[pixel]:
        self.x += movement[0]
        self.y += movement[1]

ПРИМЕЧАНИЕ: Предполагается, что существует равная вероятность перехода к любому из восьми окружающих пикселей.

Однако я считаю, что также может быть значительная неэффективностьс помощью функции self.surrounding(), особенно в этой строке:

PAI = allPixels[(self.x + x) % width][(self.y + y) % height] if allPixels[(self.x + x) % width][(self.y + y) % height] != None else None

Вы проверяете, является ли пиксель None, а затем присваиваете ему значение PAI.Хотя, если это None, вы назначаете None на PAI, делая проверку if else избыточной.Следующее утверждение эквивалентно:

PAI = allPixels[(self.x + x) % width][(self.y + y) % height]

Я бы предложил больше рекомендаций, но там есть много кода, чтобы иметь смысл.Продолжайте искать способы улучшения!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...