Федеральное государственное бюджетное образовательное учреждение высшего профессионального образования «Нижегородский государственный университет им. Н.И. Лобачевского» Факультет вычислительной математики и кибернетики Отчёт по лабораторной работе Клеточные автоматы Выполнил: студент ф-та ВМК гр. 82-02 Овсюхно А.Ю. Проверил: ассистент каф. МО ЭВМ, ВМК Сиднев А.А. Нижний Новгород 2013 г. Содержание Введение .........................................................................................................................................3 Постановка задачи .........................................................................................................................4 Руководство пользователя ............................................................................................................5 Руководство программиста...........................................................................................................7 Описание структуры программы ........................................................................................7 Описание структур данных .................................................................................................8 Описание алгоритмов ...........................................................................................................9 Заключение...................................................................................................................................10 Литература ...................................................................................................................................11 Приложения .................................................................................................................................12 Реализация очереди ............................................................................................................12 Реализация стека .................................................................................................................13 2 Введение Станислав Улам, работая в Лос-Аламосской национальной лаборатории в 1930-е годы, изучал рост кристаллов, используя простую решёточную модель. В это же время Джон фон Нейман, коллега Улама, работал над проблемой самовоспроизводящихся систем. Первоначальная концепция фон Неймана основывалась на идее робота, собирающего другого робота. Такая модель известна как кинематическая. Разработав эту модель, фон Нейман осознал сложность создания самовоспроизводящегося робота и, в частности, обеспечения необходимого «запаса частей», из которого должен строиться робот. Улам предложил фон Нейману использовать более абстрактную математическую модель, подобную той, что Улам использовал для изучения роста кристаллов. Таким образом возникла первая клеточно-автоматная система. Подобно решётке Улама, клеточный автомат фон Неймана двухмерный, а самовоспроизводящийся робот описан алгоритмически. Результатом явился универсальный конструктор, работающий «внутри» клеточного автомата с окрестностью, включающей непосредственно прилегающие ячейки, и имеющего 29 состояний. Фон Нейман доказал, что для такой модели существует паттерн, который будет бесконечно копировать самого себя. Клеточные автоматы могут применяться в различных областях. Процессоры на клеточных автоматах — физическая реализация идей клеточного автомата. Элементы процессора размещены на равномерной сетке одинаковых ячеек. Состояние ячеек определяются взаимодействием со смежными клетками-соседями. Клеточные автоматы предложены для использования в криптосистемах с открытым ключом. В этом случае односторонняя функция является результатом эволюции конечного клеточного автомата, первоначальное состояние которого сложно найти. По заданному правилу легко найти результат эволюции клеточного автомата, но очень сложно вычислить его предыдущие состояния. Также процессов. клеточные автоматы используются для моделирования физических 3 Постановка задачи В данной лабораторной работе необходимо реализовать визуальное приложение, представляющее клеточный автомат. Поле для клеточного автомата – прямоугольник, замкнутый на себя (по вертикали и горизонтали). Минимальный размер поля 3x3, максимальный размер – 1000x1000, значение по умолчанию: 20x20, значение задержки между итерациями по умолчанию – 1000. Программа должна выводить количество выполненных итераций и текущее состояние автомата. В программе должна быть возможность перейти к предыдущему состоянию автомата. Должно сохраняться не менее 50 состояний автомата. Программа должна позволять генерировать начальную конфигурацию случайным образом и задавать конфигурацию с помощью мыши. В программе должны быть реализованы следующие типы клеточных автоматов: 1) Бинарный автомат – каждая клетка принимает одно из двух значений: 0 или 1; 2) Игра "Жизнь"; 3) Автомат со следующим правилом: “клетка переходит в состояние 1, только если в её окрестности есть ровно одна клетка в состоянии 1”; 4) Циклический автомат: автомат со следующим правилом: “клетка переходит из состояния в следующее состояние, если хотя бы одна из клеток окрестности имеет следующее состояние ”. В программе должна присутствовать возможность ввода формулы, задающей вычисление элемента y[i,j] бинарного автомата. Разбор и вычисления формулы должны осуществляться с использованием обратной польской нотации. В формуле могут использоваться константы, значения клеток автомата и следующие операции: 1) | - логическое "или"; 2) & - логическое "и"; 3) ^ - сумма по модулю два (XOR); 4) ~ - логическое отрицание. 4 Руководство пользователя 1. Очистить поле 2. Запуск клеточного автомата 3. Случайное заполнение поля 4. Перерисовывание поля(необходимо для изменения размера поля) 5. Изменение ширины поля 6. Изменение высоты поля 7. Изменение задержки клеточного автомата 8. Следующий шаг автомата 9. Предыдущий шаг автомата 10. Выбор автомата 11. Поле автомата При выборе циклического автомата появляется поле выбора цвета При выборе автомата по формуле появляется поле ввода формулы 5 При нажатии на клетку поля, во всех автоматах кроме циклического клетка меняет цвет (с черного на белый или наоборот), в циклическом автомате клетка меняет цвет на выбранный. 6 Руководство программиста Описание структуры программы Исходный код программы содержится в 2-ух файлах: 1. Form.h – содержит визуальные составляющие окна программы, а также обработку событий. 2. avt.h – основной код программы, содержит классы: Field – класс поля, MyQueue – класс очереди для полей, operatorsteak – класс стека для польской записи 7 Описание структур данных 1. Form1 – класс окна программы 2. Field – класс поля автомата int rx – размер поля по ширине int ry – размер поля по высоте int getrx() – метод получения ширины поля char geti(int i) – метод получения i-того элемента матрицы поля int getry()- метод получения высоты поля char getxy(int x,int y) – метод получения элемента поля по координатам void putxy(int x,int y, char a) – метод установки значения элемента поля по координатам Field(int number_x,int number_y) – конструктор, создающий поле по ширине и высоте Field() – конструктор по умолчанию Field(Field* field) – конструктор копирования ~Field() – детруктор 3. MyQueue – реализация очереди для полей int max_num – максимальное количество элементов в очереди int num – количество элементов в очереди int top – верх очереди int bottom – низ очереди void reset_queue() – сброс очереди int getnum() – получение количества элементов в очереди void put_field(Field* field) – положить поле в очередь Field* get_field() – вытащить поле из очереди MyQueue() – конструктор по умолчанию MyQueue(int number) – конструктор по количеству элементов 4. operatorsteak – класс стека, для реализации перевода в польскую запись и ее вычисления CNode* top – верх стека CNode* bottom – дно стека int k – количество элементов в стеке char data – данные элемента стека void push(char c) – добавление элемента char pop() – извлечение элемента bool is_empty() – проверка на пустоту operatorsteak* operator=(operatorsteak* st) – перегруженный оператор присваивания operatorsteak(operatorsteak* st) – конструктор копирвания ~operatorsteak() – деструктор 5. Field* field – текущее поле автомата 6. MyQueue* queue – очередь, сохраняющая 50 последних состояний автомата. 8 Описание алгоритмов Обратная польская нотация: Перевод в обратную польскую нотацию На вход подается строка символов. Рассматриваем поочередно каждый символ: 1)Если этот символ - число (или часть переменной), помещаем его в выходную строку; 2)Если символ - знак операции (&, ~, |, ^ ), если приоритет данной операции больше, чем у операций в стеке или стек пуст, кладем ее в стек, иначе выгружаем операции из стека в строку, пока приоритет не будет больше и кладем операцию в стек. 3)Если символ открывающая скобка, помещаем ее в стек; 4) Если символ - закрывающая скобка, то извлекаем символы из стека в выходную строку до тех пор, пока не встретим в стеке открывающую скобку, которую также выгружаем из стека, но не записываем в строку. В конце выгружаем оставшиеся в стеке операции в строку. Вычисление обратной польской нотации На вход подается строка символов ( формула в польской записи). Рассматриваем поочередно каждый символ: 1) Если это константа 0 или 1, то числа 0 или 1 записывается в стек 2) Если это “[“ то в стек записывается значение клетки x,y поля автомата (где x,y – числа внутри квадратных скобок) 3) Если это знак операции, то вытаскиваем из стека 1 или 2 последних числа (в зависимости от операции: &,^,| - 2, ~ - 1) и производим эту операцию с этими числами. Игра «Жизнь» Выживание: Клетка выживает, если рядом с ней активны 2 или 3 соседние клетки. Гибель: Клетка погибает в случае, если рядом более трех или менее двух соседних клеток активны. Рождение: Если неактивная клетка граничит ровно с тремя активными клетками, то на этой клетке происходит рождение новой клетки. Алгоритм работы с автоматами По таймеру или при нажатии кнопки «>» вызывается функция выбранного автомата. В этих функциях создается новое поле, для каждой клетки вычисляется ее новое значение и записывается в это поле, после этого старое поле заменяется на новое. Каждое поле перед обработкой в функции автомата записывается в очередь. В очереди хранится не более 50-ти элементов, при загрузке в очередь с 50 элементами последний элемент стирается. 9 Заключение Реализована программа для работы несколькими типами клеточных автоматов: 1. Игра Жизнь 2. Автомат со следующим правилом: “клетка переходит в состояние 1, только если в её окрестности есть ровно одна клетка в состоянии 1” 3. Автоматы по заданным формулам с различными окрестностями 4. Автомат по введенной формуле 5. Циклический автомат Изучены алгоритм разбора строки с помощью обратной польской записи, принципы работы с Windows Forms и Managed C++. В программе реализованы две структуры хранения данных: стек на списке и очередь на массиве. 10 Литература 1. Астафьев Г.Б., Короновский А.А., Храмов А.Е. Клеточные автоматы: Учебнометодическое пособие. Саратов: Изд–во ГосУНЦ «Колледж», 2003. 24с. 2. Wolfram S. Cellular automation Fluids.// J.Stat.Phys. 1986. Vol. 45. PP. 471-526. 3. Frish U. еt al Lattice gas hydrodynamics in two and three dimensions.// Complex Systems. 1987. Vol. 1. PP. 649-707. 4. Короновский А.А., Храмов А.Е., Анфиногентов В.Г. Феноменологическая модель электронного потока с виртуальным катодом.// Известия РАН. Сер. Физическая. 1999. Т.63, N 12. С. 2355-2362. 5. Csahyk Z. and Vicsek T. Lattice gas model for collective biological motion. Physical Review A. 1995. Vol. 52. N 5. PP. 5297-5303. 6. Шилдт Г. Искусство программирования на C++, - СПб.: БХВ-Петербург, 2005. – 496 с.: ил. 11 Приложения Реализация очереди class MyQueue { private: int max_num; int num; int top; int bottom; public: void reset_queue() { num=0; top=0; bottom=0; } Field* mas; int getnum() { return num; } void put_field(Field* field) { mas[top]=field; if (top<max_num-1) top++; else top=0; if (num<max_num) num++; } Field* get_field() { if (num>0) { int temp; temp=top; if (top>0) top--; else top=max_num-1; num--; return &(mas[top]); } else return NULL; } 12 void clean() { num=0; top=0; bottom=0; } MyQueue() { top=0; bottom=0; mas=new Field[50]; max_num=50; num=0; } MyQueue(int number) { top=0; bottom=0; max_num=number; num=0; mas=new Field[max_num]; } }; Реализация стека class operatorsteak { private: CNode* top; CNode* bottom; public: int k; char data; void push(char c) { CNode* temp=new CNode; if (top==0) { bottom=temp; top=temp; } temp->data=c; temp->previous=bottom; bottom->next=temp; bottom=temp; bottom->next=0; k++; } char pop() 13 { char temp=bottom->data; CNode* dt; dt=bottom; bottom=bottom->previous; bottom->next=0; delete dt; k--; return temp; } bool is_empty() { if (k==0) return true; else return false; } operatorsteak* operator=(operatorsteak* st) { top=st->top; bottom=st->bottom; } operatorsteak() { top=0; bottom=0; k=0; } operatorsteak(operatorsteak* st) { top=st->top; bottom=st->bottom; data=st->data; k=1; } ~operatorsteak() { CNode* temp; while(top!=0) { temp=top; top=top->next; delete temp; } } }; 14