Федеральное агентство по образованию Российской Федерации Государственное образовательное учреждение высшего профессионального образования Нижегородский государственный университет им. Н.И. Лобачевского Факультет Вычислительной математики и кибернетики Отчёт по лабораторной работе Реализация динамической структуры данных типа "очередь" на основе кольцевого буфера памяти и ее практическое применение для отображения одномерных клеточных автоматов Выполнил: студент ф-та ВМК гр. 82-11 Пауль Э.А. Проверил: ассистент каф. МО ЭВМ, ВМК Кустикова В.Д. Нижний Новгород 2013 г. Оглавление Введение................................................................................................................................3 1 Постановка задачи.......................................................................................................4 2 Руководство пользователя ..........................................................................................5 3 Руководство программиста ........................................................................................6 3.1 Описание структуры программы .......................................................................6 3.1.1 Основная программа ........................................................................................6 3.1.2 Библиотека ........................................................................................................6 3.2 Описание структур данных .................................................................................6 3.2.1 Глобальные переменные..................................................................................6 3.2.2 Классы ...............................................................................................................6 4 Заключение ..................................................................................................................8 5 Литература ...................................................................................................................9 2 Введение В данной лабораторной работе представлена программа, работа которой заключается в подсчете и отрисовки последовательности конфигураций одномерного клеточного автомата с использованием структуры данных типа «очередь» на основе кольцевого буфера памяти. Очередь — структура данных с дисциплиной доступа к элементам «первый пришёл — первый вышел» (FIFO, First In — First Out). Добавление элемента (принято обозначать словом enqueue — поставить в очередь) возможно лишь в конец очереди, выборка — только из начала очереди (что принято называть словом dequeue — убрать из очереди), при этом выбранный элемент из очереди удаляется. Клеточный автомат — дискретная модель, изучаемая в математике, теории вычислимости, физике, теоретической биологии и микромеханике. Включает регулярную решётку ячеек, каждая из которых может находиться в одном из конечного множества состояний, таких как 1 и 0. Решетка может быть любой размерности. Для каждой ячейки определено множество ячеек, называемых окрестностью. К примеру, окрестность может быть определена как все ячейки на расстоянии не более 2 от текущей (окрестность фон Неймана ранга 2). Для работы клеточного автомата требуется задание начального состояния всех ячеек, и правил перехода ячеек из одного состояния в другое. На каждой итерации, используя правила перехода и состояния соседних ячеек, определяется новое состояние каждой ячейки. Обычно правила перехода одинаковы для всех ячеек и применяются сразу ко всей решётке. 3 1 Постановка задачи Необходимо разработать и реализовать консольное приложение, позволяющее наблюдать за изменением одномерного клеточного автомата при задании определенной стартовой конфигурации на протяжении заданного количества итераций. Пользователь должен иметь возможность: Задавать размерность автомата. Задавать количество итерация для отображения. Выбирать тип окрестности из предложенных: в 3 и в 5 клеток. Включать и исключать центральную клетку при подсчете следующего состояния. Выбирать стартовую конфигурацию из предложенных: тестовая, случайная, пользовательская. 6. Просматривать следующий набор конфигураций в двух режимах: автоматический и пошаговый. 1. 2. 3. 4. 5. Программа должна: 1. Запрашивать все необходимые параметры. 2. Предоставлять возможность задания пользовательской конфигурации посредством клика мыши по соответствующей клеточке. 3. Подсчитывать следующую конфигурацию и отображать последовательность заданного количества последних конфигураций. 4 2 Руководство пользователя При запуске программы, прежде всего, необходимо выбрать работу в режиме одноклеточного автомата “Automaton 1D”. Введите стартовые параметры клеточного автомата в порядке очереди (Рис.1): 1. Размерность автомата. 2. Количество отображаемых итераций. 3. Тип окрестности. 4. Включение/исключение центральной клетки. 5. Стартовая конфигурация. Рис.1. Ввод параметров автомата При выборе пользовательской стартовой конфигурации “Custom”, посредством нажатия на клетки в первой строчке, задайте желаемую стартовую конфигурацию (Рис.2), после чего нажмите любую клавишу. Рис.2. Задание пользовательской конфигурации При нажатии на клавишу “Enter” просмотр конфигураций будет запущен в автоматическом режиме. Повторное нажатие “Enter” останавливает автоматический просмотр. Однократное нажатие на любую другую клавишу приводит к отображению следующей конфигурации. 5 3 Руководство программиста 3.1 Описание структуры программы 3.1.1 Основная программа Состоит из единственного файла “main.cpp”, в котором подключена написанная в ходе выполнения лабораторной работы библиотека “lib_automaton”. В этом файле реализована и задействована функция отклика на событие нажатия мыши. Реализован интерфейс ввода начальных параметров автомата, алгоритм работы с очередью и визуальное отображение результатов работы программы. 3.1.2 Библиотека 1. CellularAutomaton – содержит классы State и CellAutomata. 2. CellularAutomaton_1D – содержит класс CellAutomata1D. 3. IOCellularAutomaton – содержит функции отрисовки сетки, задания размерности и количества первоначальных итераций (включает в себя библиотеку OpenCV). 4. IOCellularAutomaton_1D – содержит функции выбора окрестности, стартовой конфигурации и отрисовки конфигурации автомата (включает в себя библиотеку OpenCV). 5. Queue – содержит класс Queue. 3.2 Описание структур данных 3.2.1 Глобальные переменные 1. 2. 3. 4. CellAutomata1D *b – экземпляр клеточного автомата. Mat img – переменная библиотеки OpenCV для хранения изображения. Const char *winName – название окна изображения. Int wStep, hStep, dimX, dimY, mode – ширина шага, высота шага, размерность автомата, длина очереди, номер лабораторной. 3.2.2 Классы Рис.3. Диаграмма классов 6 1. State – класс состояния клетки. Содержит методы установки и получения значения. 2. CellAutomata – абстрактный класс клеточного автомата. Объявлены чистые виртуальные методы установки конфигураций и расчета следующей конфигурации. Реализованы методы получения текущей конфигурации и состояния определенной клетки. 3. CellAutomata1D – абстрактный класс одномерного клеточного автомата. Объявлен чистый виртуальный метод расчета следующего состояния клетки. Реализованы методы установки конфигураций и расчета следующей конфигурации. 4. CellAutomata1D_3 – класс одномерного клеточного автомата с окрестностью в 3 клетки. Реализован метод расчета следующего состояния клетки. 5. CellAutomata1D_5 – класс одномерного клеточного автомата с окрестностью в 5 клеток. Реализован метод расчета следующего состояния клетки. 6. Queue – класс очереди, основанный на кольцевом буфере памяти. Реализованы методы получения следующего указателя и просмотра элемента с определенным индексом. 7 4 Заключение В лабораторной работы была разработано и реализовано консольное приложение, позволяющее наблюдать за изменением одномерного клеточного автомата при задании определенной стартовой конфигурации на протяжении заданного количества итераций. В ходе выполнения работы мы: 1. Ознакомились со структурой данных типа “очередь”. 2. Реализовали “очередь” на основе кольцевого буфера памяти. 3. Научились создавать статические библиотеки и пользоваться ими. 4. Ознакомились с частью базовых методов библиотеки компьютерного зрения OpenCV. 8 5 Литература 1. Т. Тоффоли, Н. Марголус, Машины клеточных автоматов, М.: «Мир», 1991. 2. Роберт Круз. Структуры данных и проектирование программ. — Бином. Лаборатория знаний, 2008. 3. Павловская Т. А. - C/C++. Программирование на языке высокого уровня. 9 6 Приложения 6.1 Main.cpp void main(){ srand(time(NULL)); int repeat; Queue* q; inputDimensions(wStep, hStep, dimX, dimY); selectNeighborhood(&b,dimX,dimY, &q); selectStartConf(b,mode); namedWindow(winName); cvSetMouseCallback(winName, onMouseClick,(void*)&mode); drawGrid(img, wStep,hStep,dimX,dimY); if (mode==0){ imshow(winName, img); waitKey(); } mode=2; char key =-1; int autoMode=0; while (key != ESC_KEY) { for (int j=0;j<q->count;j++){ State* tmp = q->Get(j); drawAutomaton1D(tmp,img, wStep,hStep,dimX,j); } imshow(winName, img); if (autoMode==0) key = waitKey(); else key = waitKey(DELAY); if (key==ENTER) autoMode=(autoMode+1)%2; b->getNextConf(); } destroyAllWindows(); img.release(); delete a; } void onMouseClick(int eventId, int x, int y, int flags, void *userdata) { if (eventId != CV_EVENT_LBUTTONDOWN) { return; } if (*(int*)userdata==2) return; CellAutomata* tmp=a; int j = x / (wStep + thickness); int i = y / (hStep + thickness); int rx = j * (wStep + thickness) + thickness; int ry = i * (hStep + thickness) + thickness; if (*(int*)userdata==0){ if (i!=0) return; tmp=b; } 10 if (tmp->getState(i*dimX+j).getValue()==0) rectangle(img, cvRect(rx, ry, wStep, hStep), CV_RGB(255, 0, 0), CV_FILLED); else rectangle(img, cvRect(rx, ry, wStep, hStep), CV_RGB(255,255,255), CV_FILLED); tmp->getState(i*dimX+j).setValue((tmp>getState(i*dimX+j).getValue()+1)%2); imshow(winName, img); waitKey(DELAY);} 6.2 Queue.cpp #pragma once #include "Queue.h" Queue::Queue(int _dimX, int _dimY){ dimX=_dimX; dimY=_dimY; hi=-1; li=-1; arr=new State*[dimY]; for (int i=0;i<dimY;i++) arr[i]=new State[dimX]; count=0; } Queue::~Queue(){ for(int i=0;i<dimY;i++) delete[] arr[i]; delete[] arr; } State* Queue::Get(int Idx){ if ((count==0)||(hi>=li && (hi-li)<Idx)||(hi<li && (hi+dimXli)<Idx)) return NULL; return arr[(li+Idx)%dimY]; } State* Queue::GetNextPointer(){ try{ if (isFull()){ li=(li+1)%dimY; count--; } if (isEmpty()) li=0; hi=(hi+1)%dimY; count++; return arr[hi]; } catch(...){ return NULL; } } 6.3 CellularAutomaton_1D.cpp void CellAutomata1D::getNextConf(){ nextConf=q->GetNextPointer(); for(int i=0;i<dimX;i++) nextConf[i].setValue(getNextState(i)); conf=nextConf; } CellAutomata1D_3::CellAutomata1D_3(int _dimX, int _flag, Queue* _q){ 11 dimX=_dimX; flag=_flag; q=_q; conf = q->GetNextPointer(); }; unsigned int CellAutomata1D_3::getNextState(int x){ unsigned int s=conf[x].getValue()*flag; for(int i=x-1;i<x+2;i++){ int k=i; if (k!=x){ if (k<0) k=dimX+k; if (k>dimX-1) k=k-dimX; s+=conf[k].getValue(); } } return s%2; } 12