Хотя векторизация с помощью numpy не обязательно снизит вашу алгоритмическую сложность, она, вероятно, сократит ваши накладные расходы как минимум в несколько десятков раз. Как правило, если вы пишете явные циклы или используете явные операторы if
, вам следует подумать о переосмыслении вашего подхода.
Здесь вам может помочь простая маскировка для реализации свертывания. Если у вас есть места свертывания, помеченные 1 в маске той же формы, что и x
, вы можете напрямую вычесть свернутые сваи и добавить распределенный песок, просто сдвинув маску:
mask = (x >= 4)
x[mask] -= 4
x[:, :-1] += mask[:, 1:] # topple left
x[:, 1:] += mask[:, :-1] # topple right
x[:-1, :] += mask[1:, :] # topple up
x[1:, :] += mask[:-1, :] # topple down
Если count
- это количество неиспользованных сайтов, вы можете использовать np.count_nonzero
, чтобы получить его из маски:
count = np.count_nonzero(mask)
Если, с другой стороны, вы используете count
, чтобы определить, когда остановить цикл, вам может быть проще переключиться на подсчет количества сайтов свержения:
count = np.sum(mask)
Внешний цикл завершается, когда эта версия счета достигает нуля (или исходная версия достигает x.size
).