идентификация и замена элементов в массиве nxn в python для создания клеточного автомата - PullRequest
0 голосов
/ 31 марта 2020

Я изо всех сил пытался начать работу над этим заданием для университета по клеточному автомату. Предпосылка достаточно проста, учитывая массив в форме ниже, где 1 представляют черные квадраты (или живые клетки) и 0 белые квадраты (или мертвые клетки).

world1 = [0 0 0 0 0 0 0 0 0 0 0 0 0 0 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 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 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0]
 [0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0]
 [0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0]
 [0 0 0 0 1 1 1 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 1 1 1 0 0 0 1 1 1 0 0 0 0]
 [0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0]
 [0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0]
 [0 0 1 0 0 0 0 1 0 1 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 1 1 1 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]]

На каждом шаге во времени («галочка») ") следующие переходы происходят во всех ячейках одновременно:

Умирает любая живая клетка с менее чем двумя живыми соседями, как если бы она была вызвана недостаточным населением.

Любая живая клетка с двумя или тремя живыми соседями живет до следующего поколения.

Умирает любая живая клетка с более чем тремя живыми соседями, как если бы она была перенаселена.

Любая мертвая клетка с ровно тремя живыми соседями становится живой, как будто по репродукции. Здесь соседи ссылаются на 8 квадратов, окружающих каждый элемент

Теперь, будучи студентом-физиком, я вижу, что математика довольно проста, но я действительно понятия не имею, как структурировать код и сделать так, чтобы его можно было превратить в анимация позже. Я также вижу, что должны быть некоторые исключения для элементов на краю. Беллоу - моя попытка ... она работает, но ничего не возвращает. Я уверен, что вы можете сказать, что я довольно новичок в программировании!

import numpy as np
world1 = np.loadtxt('data/Pulsar.txt',dtype=np.int8) #loading data
def tick(world):
    north = world[i,i-1] #defining neighboughs as se, ne , n etc ..
    south = world[i,i+1]
    west = world[i+1,i]
    east = world[i-1,i]
    se = world[i+1,i+1]
    sw = world[i+1,i-1]
    ne = world[i-1,i+1]
    nw = world[i-1,i-1]
    neibours = (north, south, west, east, se, sw, ne, nw) #list of neighbough values
    np.where(world.all==0 and sum(neibours)==3, 1, world ) #replacing elements in array 
    np.where(world.all==1 and sum(neibours)<=2, 0, world )
    np.where(world.all==1 and sum(neibours)==2 or 3, 1, world )
    np.where(world.all==1 and sum(neibours)>=4, 0, world )


print(tick(world1))

Ответы [ 2 ]

0 голосов
/ 01 апреля 2020

Я думаю, что я все ближе, но я думаю, что есть проблемы с некоторыми типами данных, которые я использую, и в настоящее время я получаю сообщение об ошибке «Недопустимый индекс для переменной масштабирования»

def tick(matrix):
    new_state = np.array((17,17))
    for i in range(17):
        for j in range(17):
            north = matrix[i][j-1]
            south = matrix[i][j+1]
            west = matrix[i+1][j]
            east = matrix[i-1][j]
            se = matrix[i+1][j+1]
            sw = matrix[i+1][j-1]
            ne = matrix[i-1][j+1]
            nw = matrix[i-1][j-1]
            neibours = (north, south, west, east, se, sw, ne, nw)
            if matrix[i][j] == 0 and sum(neibours)==3:
                new_state [i][j] == 1
            if matrix[i][j] == 1 and sum(neibours)<=2:
                new_state [i][j] == 1
            if matrix[i][j] == 1 and sum(neibours)>=4:
                new_state [i][j] == 0
            if matrix[i][j] == 1 and sum(neibours)==2 or 3:
                new_state [i][j] == 1


            return new_state
world1 = np.loadtxt('data/Pulsar.txt',dtype=np.int8)        
print(tick(world1))

0 голосов
/ 31 марта 2020

Я думаю, что основная проблема в том, что вы объединяете обработку одной ячейки и всей матрицы в вашей функции tick.

Он начинается с обработки одной ячейки (ссылки i, которые, как я полагаю, является индексом текущей ячейки, хотя в действительности нигде не определен ...), но затем вы, кажется, пытаетесь использовать немного numpy волхвов c, чтобы применить его ко всем ячейкам как векторизованную операцию Возможно, это возможно, но ради простоты я бы начал с того, чтобы быть более явным.

Несколько других вещей, которые вы, вероятно, должны рассмотреть:

  • Вам необходимо выполнить некоторые вычисления для каждой ячейки матрицы - должно быть все oop итерирование всех ячеек матрицы ...
  • Состояние после отметки ячейки, вероятно, не должно влиять на вычисление префикса соседней ячейки - для каждого отметки вы хотите создать новую копию матрицы и заполнить его новым состоянием, вместо того, чтобы записать изменения на месте и позволить матрице находиться в «загрязненном» промежуточном состоянии тика.

Итак, очень грубо (в псевдо- python):

def tick(matrix):
  new_state = np.array(X,Y) 
  for i in range(X):
    for j in range(Y):
      # this is where most of your `tick` function comes in,
      # adjusted to compute new state for a single given cell
      new_state[i][j] = compute_cell_state(i,j,matrix) 
  return new_state

for t in range(ticks):
  matrix = tick(matrix)
  print(matrix)
...