Автоматы. Клеточные автоматы. Библиотека Numpy Составитель Ямилева А. М. кафедра ввтиС
Скачать 400.19 Kb.
|
Библиотека NumpyСоставитель: Ямилева А.М.кафедра ВВТиСПример использования numpyИгра "Жизнь" Джона КонвеяКлеточные автоматы. Игра «Жизнь»
Джон Хортон Конвей (род. 26 декабря 1937) Правила игры «Жизнь»
Правила игры «Жизнь»
Начало игры «Жизнь»population = np.array( [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 1, 1, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=np.uint8) Зададим поле 10 x 10, в центр которого поместим конструкцию, известную как «глайдер». Живые клетки обозначаются единицей, а мёртвые — нулём. Поле имеет тип uint8. Каждый его элемент занимает ровно 1 байт и является целым беззнаковым (unsigned) числом в диапазоне от 0 до 255. Подсчет соседей
neighbors = sum([ np.roll(np.roll(population, -1, 1), 1, 0), np.roll(np.roll(population, 1, 1), -1, 0), np.roll(np.roll(population, 1, 1), 1, 0), np.roll(np.roll(population, -1, 1), -1, 0), np.roll(population, 1, 1), np.roll(population, -1, 1), np.roll(population, 1, 0), np.roll(population, -1, 0) ]) [[0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 1 1 1 0 0 0 0] [0 0 0 1 1 2 1 0 0 0] [0 0 1 3 5 3 2 0 0 0] [0 0 1 1 3 2 2 0 0 0] [0 0 1 2 3 2 1 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0]] Матрица соседей Генерация новой популяцииВыполним на матрице логическую операцию: «у клетки 3 соседа». [[False False False False False False False False False False] [False False False False False False False False False False] [False False False False False False False False False False] [False False False False False False False False False False] [False False False True False True False False False False] [False False False False True False False False False False] [False False False False True False False False False False] [False False False False False False False False False False] [False False False False False False False False False False] [False False False False False False False False False False]] neighbors == 3 Генерация новой популяцииВыполним на матрице логическую операцию: «если у клетки 2 соседа и она была "жива" в текущем поколении». population & (neighbors == 2) [[0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 1 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0]] Генерация новой популяцииВыполним на матрице следующую операцию: «если у клетки 3 соседа, то в следующем поколении на этом месте будет клетка; а если 2 соседа, то клетка будет при условии, что она была "жива" в текущем поколении». population = (neighbors == 3) | (population & (neighbors == 2)) [[0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 1 0 1 0 0 0 0] [0 0 0 0 1 1 0 0 0 0] [0 0 0 0 1 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0]] Эволюция глайдераПроследим эволюцию глайдера на протяжении 4 поколений. def next_population(population): neighbors = sum([ np.roll(np.roll(population, -1, 1), 1, 0), np.roll(np.roll(population, 1, 1), -1, 0), np.roll(np.roll(population, 1, 1), 1, 0), np.roll(np.roll(population, -1, 1), -1, 0), np.roll(population, 1, 1), np.roll(population, -1, 1), np.roll(population, 1, 0), np.roll(population, -1, 0) ]) return (neighbors == 3) | (population & (neighbors == 2)) population = np.array(…) # здесь должно быть стартовое поле for _ in range(5): print(population, '\n') population = next_population(population) Эволюция глайдера[[0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 1 0 0 0 0 0] [0 0 0 0 0 1 0 0 0 0] [0 0 0 1 1 1 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0]] [[0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 1 0 1 0 0 0 0] [0 0 0 0 1 1 0 0 0 0] [0 0 0 0 1 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0]] [[0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 1 0 0 0 0] [0 0 0 1 0 1 0 0 0 0] [0 0 0 0 1 1 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0]] [[0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 1 0 0 0 0 0] [0 0 0 0 0 1 1 0 0 0] [0 0 0 0 1 1 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0]] [[0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 1 0 0 0 0] [0 0 0 0 0 0 1 0 0 0] [0 0 0 0 1 1 1 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0]] Визуализация эволюцииЕсли еще импортировать библиотеку matplotlib и использовать функцию matshow вместо печати, появятся наглядные диаграммы – картинки. from matplotlib import pyplot as plt def next_population(population): neighbors = ... return (neighbors == 3) | (population & (neighbors == 2)) population = np.array(…) # здесь должно быть стартовое поле for _ in range(5): plt.matshow(population) population = next_population(population) Визуализация эволюцииПрактическая работа
|