Построение аналитических моделей алгоритмов и оценка их сложности
КУРСОВАЯ
РАБОТА
по курсу:
«Дискретные структуры»
на тему:
«Построение аналитических моделей алгоритмов и оценка их сложности»
РЕФЕРАТ
Отчет по курсовой работе содержит: 55 страниц,
21 рисунков, 4 таблиц, 5 приложения, 3 источника.
Объект исследования - рекурсивные функции,
машины Тьюринга, нормальные алгоритмы Маркова.
Цель - сформировать формальное определение
алгоритма в виде трех аналитических моделей, написать программную реализацию
машины Тьюринга, распознающей язык L = { wwRwR│w
{0,1}*
}, построить график временной сложности.
Результат - формальное определение алгоритмов на
основе рекурсивных функций, машин Тьюринга и нормальных алгоритмов Маркова,
программная реализация машины Тьюринга, распознающей язык L = { wwRwR
│w
{0,1}*
}, график временной сложности машины Тьюринга, файловый вариант протокола
работы машины Тьюринга.
МАШИНА ТЬЮРИНГА, ВРЕМЕННАЯ СЛОЖНОСТЬ, АЛФАВИТ,
ЛЕНТА, ЯЗЫК, РАСПОЗНАВАНИЕ, АНАЛИТИЧЕСКАЯ МОДЕЛЬ, ПРИНАДЛЕЖНОСТЬ
СОДЕРЖАНИЕ
Введение
. Описание формальной модели
алгоритма на основе рекурсивных функций
Описание аналитической модели
алгоритма в виде элементарных машин Тьюринга и композиции МТ
. Разработка аналитической и
программной модели алгоритма для распознающей машины Тьюринга
.1 Формальное определение
распознающей машины Тьюринга
.2 Протоколы работы машины Тьюринга
(на двух словах языка и двух словах, не принадлежащих языку)
.3 Программная модель машины
Тьюринга
.4 Протоколы работы машины Тьюринга,
построенные программно (на двух словах языка и двух словах, не принадлежащих
языку).
.5 Расчет временной сложности
(график функции временной сложности)
. Разработка аналитической модели
алгоритма с использованием нормальных алгоритмов Маркова
Выводы
Перечень ссылок
Приложение А Техническое задание
Приложение Б Руководство
пользователя
Приложение В Протоколы работы машины
Тьюринга, построенные программно
Приложение Д Исходный код программы
Приложение Е Экранные формы
ВВЕДЕНИЕ
Первым дошедшим до нас алгоритмом в его
интуитивном понимании - конечной последовательности элементарных действий,
решающих поставленную задачу, считается предложенный Евклидом в III веке до
нашей эры алгоритм нахождения наибольшего общего делителя двух чисел (алгоритм
Евклида). В течение длительного времени, вплоть до начала XX века само слово
«алгоритм» употреблялось в устойчивом сочетании «алгоритм Евклида». Для
описания пошагового решения других математических задач использовалось слово
«метод».
Начальной точкой отсчета современной теории
алгоритмов можно считать работу немецкого математика Курта Гёделя (1931 год -
теорема о неполноте символических логик), в которой было показано, что
некоторые математические проблемы не могут быть решены алгоритмами из
некоторого класса. Общность результата Геделя связана с тем, совпадает ли
использованный им класс алгоритмов с классом всех (в интуитивном смысле)
алгоритмов. Эта работа дала толчок к поиску и анализу различных формализаций
алгоритма.
Первые фундаментальные работы по теории алгоритмов
были опубликованы независимо в 1936 году годы Аланом Тьюрингом, Алонзо Черчем и
Эмилем Постом. Предложенные ими машина Тьюринга, машина Поста и
лямбда-исчисление Черча были эквивалентными формализмами алгоритма.
Сформулированные ими тезисы (Поста и Черча-Тьюринга) постулировали
эквивалентность предложенных ими формальных систем и интуитивного понятия
алгоритма. Важным развитием этих работ стала формулировка и доказательство
алгоритмически неразрешимых проблем. [1]
. ОПИСАНИЕ ФОРМАЛЬНОЙ МОДЕЛИ АЛГОРИТМА НА ОСНОВЕ
РЕКУРСИВНЫХ ФУНКЦИЙ
Исторически первой алгоритмической системой была
система, основанная на использовании конструктивно определяемых арифметических
(целочисленных) функций, получивших специальное название рекурсивных функций.
Рекурсией называется способ задания функции, при котором значение определяемой
функции для произвольных значений аргументов выражается известным образом через
значения определяемой функции для меньших значений аргументов [2].
Задание: разработать алгоритм функции f(n),
который находит ближайшее к n
простое число.
Для начала нужно определить формулу для проверки
числа на признак простоты. Для этого была выведена формула (1.1).
Поиск ближайшего числа состоит из трех частей:
нахождения ближайшего простого, которое меньше заданного числа, нахождения
ближайшего простого числа, большего заданного, и сравнения найденных чисел. Для
реализации первой части поиска была выведена формула (1.2):
Функция нахождения ближайшего простого числа
сверху описывается формулой (1.3):
Наконец, функция, находящая ближайшее простое
число к числу n приведена на
рисунке 1.1:
Рисунок 1.1 - Ближайшее к n
простое число
На рисунке 1.2 приведен пример работы алгоритма
в частном случае, когда n=0.
n=0
-не простое и не составное
(0)=1
Рисунок 1.2 - Частный случай решения (n=0)
На рисунке 1.3 приведен пример работы алгоритма,
когда n=1.
n=1
( [;
;
Рисунок 1.3 -Частный случай решения
(n=1)
На рисунке 1.4 приведен пример
работы алгоритма, если на вход подается число, которого ближайшие числа (сверху
и снизу) находятся на одном и том же расстоянии от исходного числа.
Рисунок 1.4 - Результат работы
алгоритма (n=21)
Функция сравнения написана таким
образом, что если расстояние до двух простых чисел одинаковое, то всегда
выбирается простое, которое меньше заданного числа.
Если на вход будет подано сразу
простое число, то оно и будет результатом работы алгоритма.
Полученная рекурсивная функция
является примитивно-рекурсивной, потому что она получена благодаря конечному
применению оператора суперпозиции и примитивной рекурсии. Функции сложения,
умножения, нахождения максимума и минимума, знак, анти знак, использованные в
алгоритме, являются
примитивно-рекурсивными.
2. ОПИСАНИЕ АНАЛИТИЧЕСКОЙ МОДЕЛИ АЛГОРИТМА В
ВИДЕ ЭЛЕМЕНТАРНЫХ МАШИН ТЬЮРИНГА И КОМПОЗИЦИИ МТ
Задание: реализовать выделение
подстроки, заключенной между двумя символами (первая пара) в алфавите . Если
последовательность отсутствует
на ленте, стереть все.
Опишем работу машины Тьюринга тремя
способами:
а) системой команд;
б) функциональной таблицей;
в) графом (диаграммой) переходов.
В таблице 2.1 представлена
функциональная таблица, в которой записаны переходы между состояниями машины
Тьюринга, выполняющей поставленную задачу.
Таблица 2.1 - Функциональная таблица
|
a
|
b
|
*
|
0
|
1
|
=
|
λ
|
q0
|
q0aR
|
q0bR
|
q0*R
|
-
|
-
|
-
|
q1=L
|
q1
|
q1aL
|
q1bL
|
q1*L
|
-
|
-
|
-
|
q2
λR
|
q2
|
q2aR
|
q2bR
|
q3*R
|
-
|
-
|
q8=L
|
-
|
q3
|
q40R
|
q71R
|
q9*L
|
q3aL
|
q3bL
|
q8=L
|
-
|
q4
|
q4aR
|
q4bR
|
q5*R
|
-
|
-
|
-
|
-
|
q5
|
q5aR
|
q5bR
|
q5*R
|
-
|
-
|
q5=R
|
q6aL
|
q6
|
q6aL
|
q6bL
|
q6*L
|
q30R
|
q31R
|
q6=L
|
-
|
q7
|
q7aR
|
q7bR
|
q7*L
|
-
|
-
|
q7=R
|
q6bL
|
q8
|
q8aL
|
q8bL
|
q8*L
|
-
|
-
|
-
|
qzλR
|
q9
|
q9aL
|
q9bL
|
q9*L
|
q9aL
|
q9bL
|
-
|
qzλR
|
На рисунке 2.1 представлено описание машины
Тьюринга с помощью системы команд.
//Установка разделителя
“=”
q0*
q0*R
q0a
q0aR
q0b
q0bR
q0λq1=L
//Возврат на начало
слова
q1*
q1*L1a q1aL1b
q1bL1λ
q2 λR
//Поиск
символа
“*”
2*
q3*R2a q2aR2b
q2bR2=q8=L
//Установка разделителей
для слова, между “*”
3*
q9*L3aq40R3b
q71R30 q3aL31
q3bL3= q8=L
//Копирование, если
Первым символом оказался “a”
q4*
q5*R4a q4aR4b
q4bR
//Установка “a”
после
Символа “=”
q5a
q5aR
q5b
q5bR5= q5=R5*
q5*R5=
q5=R
q5
λ q6aL
//Возврат в состояние “q3”, для копирование
следующего символа
q6*
q6*L6a q6aL6b
q6bL60q30R
q61
q31R
q6=
q6=L
//Установка “b”
после символа “=”
q7*
q7*R
q7a
q7aR7b q7bR7=
q7=R
q7
λq6bL
//Если комбинация “*…*” не найдена, возврат на
начало слова
q8*
q8*L8a q8aL8b
q8bL
q8
λqz
λR
//Возврат на начало слова, и замена всех
разделителей
9*q9*L9a
q9aL
q9bq9bL
q91q9bL
q90
q9aL
q9 λ
qz
λR
Рисунок 2.1 - Система команд
Граф переходов изображен на рисунке 2.2.
Структура данного представления следующая:
вершины графа - состояния УУ;
дуги графа и их направление - переходы между
состояниями
вершина, из которой выходит дуга - старое
состояние;
вершина, в которую входит дуга - новое
состояние;
Рисунок 2.2 - Граф состояний
Тестовый пример работы алгоритма приведен на
рисунке 2.3.
Исходное слово - *ab*b
q0*ab*b
* q0ab*b
*a q0b*
*ab q0*
*ab* q0λ
*ab*q1=
*abq1*=
*aq1b*=
* q1ab*=
λ q1*ab*=
q2*ab*=
*q3ab*=
*0q4b*=
*0bq5*=
*0b*q5=
*0b*=q5λ
*0b*=q6a
*0b*q6=a
*0bq6*=a
*0q6b*=
*0q3b*=
*01q7*=a
*01*q7=a
*01*=q7a
*01*=aq7λ
*01*=aq6b
*01*=q6ab
*01*q6=ab
*01q6*=ab
*01q3*=ab
*01q9*=ab
*0q9b*=ab
*q9ab*=ab
λq9*ab*=ab
qz*ab*=ab
Рисунок 2.3 - Тестовый пример работы МТ
Покажем работу машины Тьюринга на еще одном
примере. На рисунке 2.4 приведен пример работы машины Тьюринга на частном
случае.
Исходное слова - abba
q0abba
aq0bba
abq0ba
abbq0a
abbaq0λ
abbaq1=1a=
abq1ba=1bba=
λ q1abba=
λ abba=
q2abba=2bba=2ba=2a=2==a=ba=bba=
λ abba=
abba=
abba=
Рисунок 2.4 - Частный случай работы машины
Тьюринга
Машина Тьюринга корректно отработала для двух
примеров входных слов: частном и общем. Следовательно, можно полагать, что
данная машина корректно отработает на всех вариантах входных слов.
Для нахождения ближайшего простого к n
числа используем композицию машин Тьюринга. Для этого составим блок-схему и
запишем все элементарные машины Тьюринга.
Элементарные машины Тьюринга, реализующие каждый
простой блок композиции, приведены на рисунке 2.5:
- сумма двух
аргументов
- предикат
равенства
- предикат
сравнения (строгое)
- вычитание двух
аргументов
- предикат “меньше
2” (строгое)
Рисунок 2.5 - Элементарный машины Тьюринга
На рисунке 2.6 приведена блок-схема алгоритма.
Рисунок 2.6 - Блок-схема алгоритма
. РАЗРАБОТКА АНАЛИТИЧЕСКОЙ И ПРОГРАММНОЙ МОДЕЛИ
АЛГОРИТМА ДЛЯ РАСПОЗНАЮЩЕЙ МАШИНЫ ТЬЮРИНГА
3.1 Формальное
определение распознающей машины Тьюринга
Программная модель была написана с целью
распознания языка
= { wwRwR
│w
{0,1}*
}.
Обработка слова не является трудоемкой и не
потребует более одной ленты.
/*Вход в машину Тьюринга. Установка разделителя
в конце слова*/
0->0R
1->1R
~->*L
/*Замена "1" и "0" на символы
"а" или "b"*/
0->aL
1->bL
a->aL
b->bL
*->*L
d->dL
~->~R
/*Замена "1" и "0" на
"а" и "b" */
0->aL
1->bL
~->~R
/*Замена "1" и "0" на
"а" и "b"*/
0->aR
1->bR
~->~R
/*Возврат в конец слова и установка признака mod
3*/
a->aR
b->bR
*->*R
~->dL
d->dR
/*Повторение действий предыдущих состояний, пока
не встретим пустой символ*/
a->aR
b->bR
*->*R
d->dR
~->~L
//Если преждевременно находим пустой символ
возвращаемся назад
d->~L
*->*R
Система команда МТ
/*Установка признака "0" - слово не
является словом языка*/
~->0L
d->~L
*->*R
//Замена всех разделителей (кроме "*")
на "1" или "0". //Конец работы машины
*->*L
b->1L
a->0L
d->dR
n->1L
0->0L
1->1L
p->0L
o->1L
h->0L
~->~R
~->~R
/*Если слово подходит по количеству символов -
меняем разделитель
Возврат в конец слова*/
a->aR
b->bR
*->*R
d->mL
m->mR
p->pR
n->nR
h->hR
o->oR
1->1R
0->0R
//Проходим снова влево, устанавливаем новый
разделитель для последнего символа слова
a->pR
b->oR
m->mL
*->*L
p->pL
o->oL
0->hR
1->nR
n->nL
h->hL
/*Проходим снова влево, устанавливаем новый
разделитель для предпоследнего символа слова*/
m->dL
n->nR
*->*R
~->~L
d->dR
o->oR
p->pR
h->hR
//Проходим снова влево, устанавливаем новый
разделитель символа слова
h->hL
*->*L
b->nR
n->nL
a->hR
p->pL
o->oL
d->dL
m->mL
1->1R
0->0R
Система команд МТ
//Проверка на равенство двух последних триад
d->dL
*->*L
p->0R
o->1R
0->0L
1->1L
a->aR
b->bR
~->~R
// Если первый был символ "p"
*->*L
0->0L
1->1L
o->oL
p->pL
h->0R
n->nR
//Проход вправо до “*”
p->pR
o->oR
1->1R
0->0R
*->*L
//Проверка на реверс двух первых триад
0->uL
1->vL
u->uL
n->nL
h->hL
v->vL
~->~R
//Если первый был символ “0”
0->0L
1->1L
b->bL
a->aL
v->vL
u->uL
~->~R
//Проход в конец слова
0->0R
1->1R
o->oR
p->pR
n->nR
a->aR
b->bR
h->hR
u->uR
v->vR
*->*R
d->dR
m->mR
~->~L
//Замена разделителей (n->1)
*->*L
0->0L
1->1L
o->oL
p->pL
n->1R
h->hR
//Проход вправо до “*”
p->pR
o->oR
1->1R
0->0R
*->*L
// Проход вправо до “~”
0->0L
1->1L
v->vL
u->uL
b->bL
a->aL
~->~R
Система команд МТ
//Замена старого символа на новый (b->v)
b->vR
v->vR
u->uR
a->aR
//Проход вправо до границы слова
b->bR
a->aR
0->0R
1->1R
v->vR
u->uR
n->nL
h->hL
//Замена старого символа на новый (a->u)
a->uR
v->vR
u->uR
b->bR
//Проход вправо до границы слова
b->bR
a->aR
0->0R
1->1R
v->vR
u->uR
n->nL
h->hL
//Очистка всех признаков
d->~L
m->~L
*->*R
алгоритм тьюринг
аналитический марков
//Проход в конец слова
0->0R
1->1R
o->oR
p->pR
n->nR
a->aR
b->bR
h->hR
u->uR
v->vR
*->*R
d->dR
m->mR
~->~L
//Очистка всех признаков
d->~L
m->~L
*->*R
//Слово не принадлежит
~->0L
//Замена всех разделителей
1->1L
0->q300Lo->1L
p->0L
n->1L
v->1L
u->0L
h->0L
a->0L
b->1L
~->~R
//Слово принадлежит
*->*L
~->1L
Система команд МТ
3.2 Протоколы работы
машины Тьюринга (на двух словах языка и двух словах, не принадлежащих языку)
Пример работы алгоритма на слове “01”, которое
не является словом исходного языка приведен в таблице 3.1.
Таблица 3.1 - Протокол работы МТ на слове “01”
Шаг
|
Состояние
|
Слово
на ленте
|
Команда
|
1
|
|
λ01λ
|
|
2
|
|
λ01λ
|
1
-> 1R
|
3
|
|
λ01λ
|
λ
-> *L
|
4
|
|
λ0b*λ
|
1
->bL
|
5
|
|
λab*λ
|
0
-> aL
|
6
|
|
λab*λ
|
λ
-> λR
|
7
|
|
λab*λ
|
a
-> aR
|
8
|
|
λab*λ
|
b
-> bR
|
9
|
|
λab*λ
|
*
-> *R
|
10
|
|
λab*λ
|
~
-> ~L
|
11
|
|
λab*λ
|
*
-> *R
|
12
|
|
λab*0
|
~
-> 0L
|
13
|
|
λab*0
|
*
-> *L
|
14
|
|
λab*0
|
b
-> 1L
|
15
|
|
λa1*0
|
a
-> 0L
|
16
|
|
λ01*0
|
~
-> ~R
|
|
|
λ01*0
|
|
В таблице 3.2 представлен протокол работы машины
Тьюринга на пустом слове. Это слово принадлежит языку, что совпадает с
результатом работы машины.
Таблица 3.2 - Проток работы МТ на пустом слове
ШагСостояниеСлово
на лентеКоманда
|
|
|
|
1
|
|
λλλ
|
|
2
|
|
λ*λ
|
R
|
3
|
|
λ*λ
|
|
4
|
|
λ*λ
|
|
5
|
|
λ*λ
|
|
6
|
|
λ*λ
|
|
7
|
|
λ*λ
|
|
8
|
|
λ*λ
|
|
9
|
|
λ*λ
|
|
10
|
|
λ*1
|
|
11
|
|
λ*1
|
|
12
|
|
λ*1
|
|
13
|
|
λ*1
|
|
В таблице 3.3 представлен протокол работы
распознающей машины Тьюринга на слове 1. Это слово не принадлежит языку, что
сходится с результатом выполнения машины.
Таблица 3.3 - Протокол работы МТ на слове “1”
Шаг
|
Состояние
|
Слово
на ленте
|
Команда
|
1
|
|
λ1λ
|
|
2
|
|
λ1*
|
|
3
|
|
λb*
|
1
->bL
|
4
|
|
λb*
|
->
R
|
5
|
|
λb*
|
b
-> bR
|
6
|
|
λb*
|
*
-> *R
|
7
|
|
λb*λ
|
->
L
|
8
|
|
λb*λ
|
*
-> *R
|
9
|
|
λb*0
|
10
|
|
λb*0
|
*
-> *L
|
11
|
|
λ1*0
|
b
-> 1L
|
12
|
|
λ1*0
|
->
R
|
13
|
|
λ1*0
|
|
Пример правильных слов алфавита более приводится
не будут, так как они громоздки в просчетам, потому что график алгоритма имеет
квадратичную зависимость и резкие скачки на словах, принадлежащих исходному
алфавиту.
3.3 Программная модель
машины Тьюринга
Для наглядной демонстрации работы
детерминированной машины Тьюринга была разработана программа.
Программная модель распознающей машины Тьюринга
реализована на языке программирования С#. Исходный код программы представлен в
приложении Д.
Лента моделируется с помощью множества элемента
управления Label, а
создается в момент запуска пользователем программы. При должной настройки
параметров экземпляров этого класса, получается точная графическая модель
машины Тьюринга.
Все пользовательские команды загружаются сразу
из файла при запуске программы, и сохраняются в специальную структура SortedList,
которая обеспечивает хранение, легко обращение к командам и отсутствие
дубликатов команд.
В программе предусмотрено пошаговое прохождение
слова с выполнением команд, автоматическая обработка слова, построение и
сохранение графика алгоритма.
3.4 Протоколы работы
машины Тьюринга, построенные программно (на двух словах языка и двух словах, не
принадлежащих языку)
Протоколы работы машины Тьюринга, построенные
программно, приведены в приложении В. Стрелкой в них выделено положение УУ.
Символом “~” обозначен пустой символ.
3.5 Расчет временной
сложности (график функции временной сложности)
Данный алгоритм устроен таким образом, что
наибольшее время выполняются слова длиной, кратной трем, так как для таких слов
требуется наибольшее количество проверок.
Как видно из эскиза, график имеет полиномиальную
зависимость 2-го порядка с неединичными коэффициентами. Также, из-за резких
скачков на точках, кратных трем, можно определить, что график описывается
системой из трех квадратичных уравнений.
Машина Тьюринга реализована на одной ленте,
из-за чего требуются многочисленные проходы по слову для установки тех или иных
разделителей.
Для слов длины кратной трем используется проход
до конца слова и обратно за 2(n+2)
шагов, после чего делается снова возврат на конец слова и начинается сравнение
частей слов, тактами длиной (n+2)/3.
Для слов длины не кратной трем используется 2(n+2)
шагов для установки разделителя, после чего осуществляется (n+2)/3
шагов для проверки слова на четность. Так как слово не принадлежит алфавиту, то
делается возврат на начало слова, длиной n+2.
Таким образом, график состоит из трех частей, и
экспериментально были выведены уравнения определенных точек. Уравнения
приведены формулой 3.3.
Построенный программой график практически
совпадает с теоретическими расчетами. На рисунке 3.2 приведен график сложности
алгоритма.
Рисунок 3.2 - График сложности алгоритма
РАЗРАБОТКА АНАЛИТИЧЕСКОЙ МОДЕЛИ АЛГОРИТМА С
ИСПОЛЬЗОВАНИЕМ НОРМАЛЬНЫХ АЛГОРИТМОВ МАРКОВА
Марковская подстановка - это операция над
словами, заключающаяся в следующем:
в исходном слове γ ищется
самое левое вхождение слова λ, если
оно существует, λ заменяется β
на в слове γ;
полученное слово γ
является результатом применения Марковской подстановки к слову γ;
если λ слово
не входит в слово γ, то
говорят, что данная Марковская подстановка не применима к слову γ
[3].
Задание: реализовать алгоритм над
алфавитом , который
выдает 1, если исходное слово содержит комбинацию baccd, и 0 - в
противном случае.
Реализация приведена на рисунке 4.1.
Рисунок 4.1 - Правила НАМ
Примеры работы алгоритма представлены на рисунке
4.2 , если слово содержит искомую комбинацию символов. На рисунке 4.3 - не
содержит.
abab01baccd110d
abab01x110d
bab01x110d
bb01x110d
b01x110d
01x110d
01x110
x110
x10
x0
x0
x
1
Рисунок 4.2 - Пример работы алгоритма
abad01
bad01
bd01
d01
Рисунок 4.3 - Пример работы алгоритма
ВЫВОДЫ
В ходе выполнения курсовой работы были
закреплены навыки работы с рекурсивными функциями, машинами Тьюринга и
нормальными алгоритмами Маркова.
Особенно детально были изучены различные
одноленточные машины Тьюринга. Также получены навыки построения графика
временной сложности алгоритма.
В данной работе разработан программный продукт,
демонстрирующий работу распознающей машины Тьюринга для языка
L
= {wwRwR│w
{0,1}*}.
Результатом работы машины является символ “1”
или “0”, в зависимости от слова, который записывается после входного слова.
Для данной машины Тьюринга был построен график
временной сложности для входных слов длиной от 1 до 13.
ПЕРЕЧЕНЬ ССЫЛОК
1. Введение
в теорию алгоритмов [Электронный ресурс]. - Электронные текстовые данные. -
Режим доступа: #"656222.files/image001.gif">{0,1}*
}, расчет и экспериментальная проверка расчета временной сложности МТ.
Требования к программе:
при проверке слова на принадлежность языку
необходимо запретить ввод с клавиатуры символов не из входного алфавита
заданного языка;
при проверке слова на принадлежность языку
выводить на экран каждый шаг работы машины Тьюринга;
сохранять протокол работы машины Тьюринга в
текстовом файле;
при построении графика временной сложности
работы машины Тьюринга значения для графика получить практически, с помощью
созданной программной модели машины Тьюринга; для генерации слов длиной n
использовать метод полного перебора.
Требования к программной документации:
пояснительная записка;
руководство пользователя.
Этапы разработки
Приложение Б
Руководство пользователя
Б.1 Назначение программы
Программа предназначена для демонстрации работы
одноленточной машины Тьюринга на примере языка L = { wwRwR
│w
{0,1}*
}. Пользователь может проверить введенное им слово на принадлежность языку,
сохранить результаты работы в текстовый файл, построить и сохранить график
сложности алгоритма для слова выбранной длины.
Б.2 Исполнение программы
Так как программа выполнена на языке C#,
то для ее запуска обязательно наличие Microsoft
.NET Framework
версии, не ниже 4.0. Запуск приложения осуществляется через файл TuringMachine.exe.
При запуске приложения открывается основное окно
работы программы, приведенное на рисунке Б.1 , где пользователь может с помощью
соответствующих кнопок выполнять интересующие его действия.
Изначально на ленте записано пустое слово. Для
смены слова, пользователь должен ввести его в графу “Слово” и ввести начальное
состояние, после чего нажать на кнопку “Ввести”. Ввод состояния был внедрен для
большей гибкости программы, чтобы пользователь мог начать работу с любого
другого состояния.
Файл листинга программы сохраняется
автоматически при завершении обработки слова в текущую директорию программы под
названием listing.txt.
В нем содержится информация об изменениях слова
при выполнении определенных операций над ним.
Для запуска работы машины Тьюринга предназначена
кнопка “Старт”, которая начинает автоматически выполнять команды над текущим
словом. Работу машины можно приостановить нажав на кнопку “Пауза\Продолжить”.
Левее кнопок располагается бегунок, манипулируя которым пользователь может
изменять скорость работы машины. Также предусмотрена кнопка “Шаг”, при нажатии
на которую, машина выполняет одну команду и выводит текущее состояние, команду
на экран.
Ниже располагается поле для ввода длины слова и
кнопка “Построить график”, по нажатию на которую начинает строиться график
временной сложности данного алгоритма.
Рисунок Б.1 - Главное окно программы
Приложение В
Протоколы работы машины Тьюринга, построенные
программно
Протокол 1 (слово принадлежит языку):
Исходное слово - 100101
>100101 | Команда: q01 -> q01R |
Состояние: q0
->00101 | Команда: q00 -> q00R |
Состояние: q0
->0101 | Команда: q00 -> q00R | Состояние:
q0
->101 | Команда: q01 -> q01R | Состояние:
q0
->01 | Команда: q00 -> q00R | Состояние:
q0
->1 | Команда: q01 -> q01R | Состояние: q0
| Команда: q0~ -> q1*L | Состояние: q0
->1*| Команда: q11 -> q2bL | Состояние: q1
->0b* | Команда: q20 -> q3aL | Состояние:
q2
->1ab* | Команда: q31 -> q4bR | Состояние:
q3
b->ab* | Команда: q4a -> q4aR | Состояние:
q4
ba->b* | Команда: q4b -> q4bR | Состояние:
q4
bab->* | Команда: q4* -> q4*R | Состояние:
q4
bab* | Команда: q4~ -> q1dL | Состояние: q4
bab->*d | Команда: q1* -> q1*L |
Состояние: q1
ba->b*d | Команда: q1b -> q1bL |
Состояние: q1
b->ab*d | Команда: q1a -> q1aL |
Состояние: q1
->bab*d | Команда: q1b -> q1bL |
Состояние: q1
->0bab*d | Команда: q10 -> q2aL |
Состояние: q1
->0abab*d | Команда: q20 -> q3aL |
Состояние: q2
>1aabab*d | Команда: q31 -> q4bR |
Состояние: q3
b->aabab*d
| Команда: q4a
-> q4aR
| Состояние: q4
ba->abab*d
| Команда: q4a
-> q4aR
| Состояние: q4
baa->bab*d
| Команда: q4b
-> q4bR
| Состояние: q4
baab->ab*d
| Команда: q4a
-> q4aR
| Состояние: q4
baaba->b*d
| Команда: q4b
-> q4bR
| Состояние: q4>*d | Команда:
q4* -> q4*R | Состояние: q4*->d | Команда: q4d -> q4dR | Состояние:
q4*d | Команда: q4~ -> q1dL | Состояние: q4*->dd | Команда: q1d ->
q1dL | Состояние: q1>*dd | Команда: q1* -> q1*L | Состояние: q1
baaba->b*dd
| Команда: q1b
-> q1bL
| Состояние: q1
baab->ab*dd
| Команда: q1a
-> q1aL
| Состояние: q1
baa->bab*dd
| Команда: q1b
-> q1bL
| Состояние: q1
ba->abab*dd
| Команда: q1a
-> q1aL
| Состояние: q1
b->aabab*dd
| Команда: q1a
-> q1aL
| Состояние: q1
>baabab*dd
| Команда: q1b
-> q1bL
| Состояние: q1
baabab*dd
| Команда: q1~ -> q9~R
| Состояние: q1
>baabab*dd
| Команда: q9b
-> q9bR
| Состояние: q9
b->aabab*dd
| Команда: q9a
-> q9aR
| Состояние: q9
ba->abab*dd
| Команда: q9a
-> q9aR
| Состояние: q9
baa->bab*dd
| Команда: q9b
-> q9bR
| Состояние: q9
baab->ab*dd
| Команда: q9a
-> q9aR
| Состояние: q9
baaba->b*dd
| Команда: q9b
-> q9bR
| Состояние: q9>*dd | Команда:
q9* -> q9*R | Состояние: q9*->dd | Команда: q9d -> q10mL | Состояние:
q9>*md | Команда: q10* -> q10*L | Состояние: q10
baaba->b*md
| Команда: q10b
-> q9oR
| Состояние: q10>*md |
Команда: q9* -> q9*R | Состояние: q9*->md | Команда: q9m -> q9mR |
Состояние: q9*m->d | Команда: q9d -> q10mL | Состояние: q9*->mm |
Команда: q10m -> q10mL | Состояние: q10>*mm | Команда: q10* -> q10*L |
Состояние: q10
baaba->o*mm
| Команда: q10o
-> q10oL
| Состояние: q10
baab->ao*mm
| Команда: q10a
-> q9pR
| Состояние: q10
baabp->o*mm
| Команда: q9o
-> q9oR
| Состояние: q9>*mm | Команда:
q9* -> q9*R | Состояние: q9*->mm | Команда: q9m -> q9mR | Состояние:
q9*m->m | Команда: q9m -> q9mR | Состояние: q9*mm | Команда: q9~ ->
q11~L | Состояние: q9*m->m | Команда: q11m -> q12dL | Состояние:
q11*->md | Команда: q12m -> q12mL | Состояние: q12>*md | Команда: q12*
-> q12*L | Состояние: q12
baabp->o*md
| Команда: q12o
-> q12oL
| Состояние: q12
baab->po*md
| Команда: q12p
-> q12pL
| Состояние: q12
baa->bpo*md
| Команда: q12b
-> q11nR
| Состояние: q12
baan->po*md
| Команда: q11p
-> q11pR
| Состояние: q11
baanp->o*md
| Команда: q11o
-> q11oR
| Состояние: q11>*md |
Команда: q11* -> q11*R | Состояние: q11*->md | Команда: q11m -> q12dL
| Состояние: q11>*dd | Команда: q12* -> q12*L | Состояние: q12
baanp->o*dd
| Команда: q12o
-> q12oL
| Состояние: q12
baan->po*dd
| Команда: q12p
-> q12pL
| Состояние: q12
baa->npo*dd
| Команда: q12n
-> q12nL
| Состояние: q12
ba->anpo*dd
| Команда: q12a
-> q11hR
| Состояние: q12
bah->npo*dd
| Команда: q11n
-> q11nR
| Состояние: q11
bahn->po*dd
| Команда: q11p
-> q11pR
| Состояние: q11
bahnp->o*dd
| Команда: q11o
-> q11oR
| Состояние: q11>*dd |
Команда: q11* -> q11*R | Состояние: q11
bahnpo*->dd
| Команда: q11d
-> q11dR
| Состояние: q11*d->d |
Команда: q11d -> q11dR | Состояние: q11
bahnpo*dd
| Команда: q11~ -> q13~L
| Состояние: q11*d->d |
Команда: q13d -> q13dL | Состояние: q13*->dd | Команда: q13d -> q13dL
| Состояние: q13>*dd | Команда: q13* -> q13*L | Состояние: q13
bahnp->o*dd
| Команда: q13o
-> q191R
| Состояние: q13->*dd |
Команда: q19* -> q19*L | Состояние: q19>1*dd | Команда: q191 -> q191L
| Состояние: q19
bahn->p1*dd
| Команда: q19p
-> q19pL
| Состояние: q19
bah->np1*dd
| Команда: q19n
-> q201R
| Состояние: q19
bah1->p1*dd
| Команда: q20p
-> q20pR
| Состояние: q20p->1*dd |
Команда: q201 -> q201R | Состояние: q20p1->*dd | Команда: q20* ->
q13*L | Состояние: q20p->1*dd | Команда: q131 -> q131L | Состояние: q13
bah1->p1*dd
| Команда: q13p
-> q140R
| Состояние: q13->1*dd |
Команда: q141 -> q141L | Состояние: q14->01*dd | Команда: q140 ->
q140L | Состояние: q14>101*dd | Команда: q141 -> q141L | Состояние:
q14>h101*dd | Команда: q14h -> q150R | Состояние: q14->101*dd |
Команда: q151 -> q151R | Состояние: q15->01*dd | Команда: q150 ->
q150R | Состояние: q15->1*dd | Команда: q151 -> q151R | Состояние:
q15->*dd | Команда: q15* -> q13*L | Состояние: q15->1*dd | Команда:
q131 -> q131L | Состояние: q13->01*dd | Команда: q130 -> q130L |
Состояние: q13->101*dd | Команда: q131 -> q131L | Состояние:
q13>0101*dd | Команда: q130 -> q130L | Состояние: q13>a0101*dd |
Команда: q13a -> q9aR | Состояние: q13>0101*dd | Команда: q90 -> q90R
| Состояние: q9->101*dd | Команда: q91 -> q91R | Состояние: q9->01*dd
| Команда: q90 -> q90R | Состояние: q9->1*dd | Команда: q91 -> q91R |
Состояние: q9->*dd | Команда: q9* -> q9*R | Состояние: q9*->dd |
Команда: q9d -> q10mL | Состояние: q9->*md | Команда: q10* -> q10*L |
Состояние: q10->1*md | Команда: q101 -> q9nR | Состояние: q10n->*md |
Команда: q9* -> q9*R | Состояние: q9n*->md | Команда: q9m -> q9mR |
Состояние: q9n*m->d | Команда: q9d -> q10mL | Состояние: q9n*->mm |
Команда: q10m -> q10mL | Состояние: q10n->*mm | Команда: q10* -> q10*L
| Состояние: q10->n*mm | Команда: q10n -> q10nL | Состояние:
q10->0n*mm | Команда: q100 -> q9hR | Состояние: q10h->n*mm | Команда:
q9n -> q9nR | Состояние: q9hn->*mm | Команда: q9* -> q9*R | Состояние:
q9hn*->mm | Команда: q9m -> q9mR | Состояние: q9hn*m->m | Команда: q9m
-> q9mR | Состояние: q9hn*mm | Команда: q9~ -> q11~L | Состояние:
q9hn*m->m | Команда: q11m -> q12dL | Состояние: q11hn*->md | Команда:
q12m -> q12mL | Состояние: q12hn->*md | Команда: q12* -> q12*L |
Состояние: q12h->n*md | Команда: q12n -> q12nL | Состояние: q12->hn*md
| Команда: q12h -> q12hL | Состояние: q12->1hn*md | Команда: q121 ->
q161R | Состояние: q12->hn*md | Команда: q16h -> q16hL | Состояние:
q16->1hn*md | Команда: q161 -> q21vL | Состояние: q16>0vhn*md |
Команда: q210 -> q210L | Состояние: q21>a0vhn*md | Команда: q21a ->
q21aL | Состояние: q21
>ba0vhn*md | Команда: q21b -> q21bL |
Состояние: q21vhn*md | Команда: q21~ -> q22~R | Состояние: q21
>ba0vhn*md | Команда: q22b -> q23vR |
Состояние: q22>a0vhn*md | Команда: q23a -> q23aR | Состояние:
q23>0vhn*md | Команда: q230 -> q230R | Состояние: q23->vhn*md |
Команда: q23v -> q23vR | Состояние: q23v->hn*md | Команда: q23h ->
q16hL | Состояние: q23->vhn*md | Команда: q16v -> q16vL | Состояние:
q16>0vhn*md | Команда: q160 -> q17uL | Состояние: q16>auvhn*md |
Команда: q17a -> q17aL | Состояние: q17
>vauvhn*md | Команда: q17v -> q17vL |
Состояние: q17*md | Команда: q17~ -> q24~R | Состояние: q17
>vauvhn*md | Команда: q24v -> q24vR |
Состояние: q24>auvhn*md | Команда: q24a -> q25uR | Состояние:
q24>uvhn*md | Команда: q25u -> q25uR | Состояние: q25>vhn*md | Команда:
q25v -> q25vR | Состояние: q25>hn*md | Команда: q25h -> q16hL |
Состояние: q25>vhn*md | Команда: q16v -> q16vL | Состояние:
q16>uvhn*md | Команда: q16u -> q16uL | Состояние: q16>uuvhn*md |
Команда: q16u -> q16uL | Состояние: q16
>vuuvhn*md | Команда: q16v -> q16vL |
Состояние: q16*md | Команда: q16~ -> q18~R | Состояние: q16
>vuuvhn*md | Команда: q18v -> q18vR |
Состояние: q18>uuvhn*md | Команда: q18u -> q18uR | Состояние:
q18>uvhn*md | Команда: q18u -> q18uR | Состояние: q18>vhn*md |
Команда: q18v -> q18vR | Состояние: q18>hn*md | Команда: q18h -> q18hR
| Состояние: q18>n*md | Команда: q18n -> q18nR | Состояние: q18>*md |
Команда: q18* -> q18*R | Состояние: q18*->md | Команда: q18m -> q18mR
| Состояние: q18*m->d | Команда: q18d -> q18dR | Состояние: q18*md |
Команда: q18~ -> q26~L | Состояние: q18*m->d | Команда: q26d -> q26~L
| Состояние: q26*->m | Команда: q26m -> q26~L | Состояние: q26>* |
Команда: q26* -> q31*R | Состояние: q26* | Команда: q31~ -> q311L |
Состояние: q31>*1 | Команда: q31* -> q30*L | Состояние: q31>n*1 |
Команда: q30n -> q301L | Состояние: q30>h1*1 | Команда: q30h -> q300L
| Состояние: q30>v01*1 | Команда: q30v -> q301L | Состояние:
q30>u101*1 | Команда: q30u -> q300L | Состояние: q30>u0101*1 |
Команда: q30u -> q300L | Состояние: q30
>v00101*1 | Команда: q30v -> q301L |
Состояние: q30
*1 | Команда: q30~ -> qz~R | Состояние: q30
Протокол 2 (слово не принадлежит языку)
Исходное слово - 010
>010 | Команда: q00 -> q00R | Состояние:
q0
->10 | Команда: q01 -> q01R | Состояние:
q0
->0 | Команда: q00 -> q00R | Состояние: q0
| Команда: q0~ -> q1*L | Состояние: q0
->0* | Команда: q10 -> q2aL | Состояние:
q1
->1a* | Команда: q21 -> q3bL | Состояние:
q2
>0ba* | Команда: q30 -> q4aR | Состояние:
q3>ba* | Команда: q4b -> q4bR | Состояние: q4>a* | Команда: q4a ->
q4aR | Состояние: q4>* | Команда: q4* -> q4*R | Состояние: q4* | Команда:
q4~ -> q1dL | Состояние: q4>*d | Команда: q1* -> q1*L | Состояние:
q1>a*d | Команда: q1a -> q1aL | Состояние: q1>ba*d | Команда: q1b
-> q1bL | Состояние: q1
>aba*d | Команда: q1a -> q1aL | Состояние:
q1*d | Команда: q1~ -> q9~R | Состояние: q1
>aba*d | Команда: q9a -> q9aR | Состояние:
q9>ba*d | Команда: q9b -> q9bR | Состояние: q9>a*d | Команда: q9a
-> q9aR | Состояние: q9>*d | Команда: q9* -> q9*R | Состояние:
q9*->d | Команда: q9d -> q10mL | Состояние: q9>*m | Команда: q10*
-> q10*L | Состояние: q10>a*m | Команда: q10a -> q9pR | Состояние:
q10>*m | Команда: q9* -> q9*R | Состояние: q9*->m | Команда: q9m ->
q9mR | Состояние: q9*m | Команда: q9~ -> q11~L | Состояние: q9*->m |
Команда: q11m -> q12dL | Состояние: q11>*d | Команда: q12* -> q12*L |
Состояние: q12>p*d | Команда: q12p -> q12pL | Состояние: q12>bp*d |
Команда: q12b -> q11nR | Состояние: q12>p*d | Команда: q11p -> q11pR |
Состояние: q11>*d | Команда: q11* -> q11*R | Состояние: q11*->d |
Команда: q11d -> q11dR | Состояние: q11*d | Команда: q11~ -> q13~L |
Состояние: q11*->d | Команда: q13d -> q13dL | Состояние: q13>*d |
Команда: q13* -> q13*L | Состояние: q13>p*d | Команда: q13p -> q140R |
Состояние: q13->*d | Команда: q14* -> q14*L | Состояние: q14>0*d |
Команда: q140 -> q140L | Состояние: q14>n0*d | Команда: q14n -> q27nR
| Состояние: q14>0*d | Команда: q270 -> q270R | Состояние: q27->*d |
Команда: q27* -> q27*R | Состояние: q27*->d | Команда: q27d -> q27dR |
Состояние: q27*d | Команда: q27~ -> q28~L | Состояние: q27*->d | Команда:
q28d -> q28~L | Состояние: q28->* | Команда: q28* -> q29*R |
Состояние: q28* | Команда: q29~ -> q310L | Состояние: q29->*0 | Команда:
q31* -> q30*L | Состояние: q31>0*0 | Команда: q300 -> q300L |
Состояние: q30>n0*0 | Команда: q30n -> q301L | Состояние: q30
>a10*0 | Команда: q30a -> q300L |
Состояние: q30
*0 | Команда: q30~ -> qz~R | Состояние: q30
Приложение Д
Исходный код программы
//Основная форма.Содержит: машина Тьюринга,
построение маленького эскиза графика
//
Form1.csSystem;System.Collections;System.Collections.Generic;System.ComponentModel;System.Data;System.Threading;System.Drawing;System.Linq;System.Text.RegularExpressions;System.IO;System.Windows.Forms;System.Windows.Forms.DataVisualization.Charting;TuringMachine
{void TheDelegate();int
IntDelegate();void ParamDelegate(double a);partial class Form1 : Form
{int location = 0; //положение
УУ
на
МТ
private int steps= 0; // Количество проходов УУ
по элементу словаstatic String shortState; //кортоткая форма номера состония
(Например,q0)String state; //Полное состояние МТ (Например, q00R)currWordLength
= 0; //Длина текущего словаint index = 0; // Индекс элемента в массиве
maxstatic int[] max = new int[20]; //Массив, содержащий в себе пару "длина
слова-максимальное количество тактов"int RandomWordLength = 0; //Вводимая
пользователем длина слова, для построения графика
String[] keyv = new String[2]; //Массив
команд
вида:
q00->q00R
private bool flag = true; //Признак: работает МТ
в текущий момент или нет.bool second_flag = true; // Признак: проводить ли
рендеринг движения УУ или нет.static int WordLength; //Длина введенного
пользователем слова
private static Label[] ribbon = new
Label[200]; //Лента МТ
StreamWriter strwr = new StreamWriter(@"./listing.txt");
// Поток-писатель для выведения листинга в файл
private String curstate; //Текущее
состояние
МТSortedList<String,
String> mtstates = new SortedList<String, String>(); //Контейнер
для
всех
состояний
МТ
Thread okras; // Второй поток для параллельного
рендеринга
public Form1()
{();i; trackBar1.Value = 250;
chart1.Series[0].Name = "";.Series[0].Color = Color.Red;.Text =
File.ReadAllText(@"D:/МТ_Моя.txt");(int
j = 0; j < textBox1.Lines.Length; j++)
{(textBox1.Lines[j].Equals(""));[0]
= Splited(textBox1.Lines[j])[0];[1] =
Splited(textBox1.Lines[j])[2];.Add(keyv[0], keyv[1]);
}(int j = 0; j < 20; j++)[j] =
new int();= Splited(textBox1.Lines[0])[2];(i = 0; i < 50; i++)
{[i] = new Label();[i].Text =
"~";[i].Size = label1.Size;[i].Location = new Point(0 + (i) *
ribbon[i].Width, 0);[i].Font = label1.Font;[i].BackColor =
Color.White;[i].BorderStyle = BorderStyle.FixedSingle;.Controls.Add(ribbon[i]);
}
}void button2_Click(object sender,
EventArgs e)
{.Enabled = false;= new Thread(new
ThreadStart(Paint_Label));.Start();
}void State()
{.Text = curstate;
}void Button2Enabled()
{.Enabled = true; ;
}void Replace()
{[location + 10].Text =
state[state.Length - 2].ToString();
}void ShowState()
{.Text = curstate + ribbon[location
+ 10].Text + "->" + state;
}int TrackBar()
{trackBar1.Value;
}void Paint_Label()
{deli = new TheDelegate(State);enbl
= new TheDelegate(Button2Enabled);(true)
{= state.Remove(state.Length - 2,
2);(shortState.Equals("qz"))
{(second_flag == true)
{.Show("Машина
Тьюринга
завершила
свою
работу.",
"Сообщение",
MessageBoxButtons.OK, MessageBoxIcon.Information);= 0;= "q0";=
"qz";(deli);[location + 10].BackColor = Color.SkyBlue;[location +
9].BackColor = Color.White;
}(enbl);;
}
{(mtstates[String.Concat(shortState
+ ribbon[location + 10].Text)], shortState, second_flag);
}(Exception e)
{.Show(String.Concat(shortState +
ribbon[location + 10].Text) + " отсутствует
в
словаре",
"Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error);(enbl);.Abort();;
}
}
}String ToFile()
{String.Concat(shortState + ribbon[location
+ 10].Text) + " -> " + mtstates[String.Concat(shortState +
ribbon[location + 10].Text)];
}PrintDataToFile()
{str = "";(int k = 0; k
< 50; k++)
{(!ribbon[k].Text.Equals("~"))
{(currWordLength - 10 == location)=
str + "->" + ribbon[currWordLength].Text;= str +
ribbon[currWordLength].Text;
}++;
}.WriteLine(str + " | Команда:
" + ToFile() +" | Состояние:
"+ shortState + "\n");.WriteLine("");.Flush();= 0;
}void Steps(String state, String
shortState, bool graph)
{(graph == true)
{();
}deli = new
TheDelegate(State);deli_zamena = new TheDelegate(Replace);deli_show = new
TheDelegate(ShowState);deli_track = new IntDelegate(TrackBar);.state =
state;(state[state.Length - 1])
{'L':= shortState;(graph == true)
{[location + 10].BackColor = Color.SkyBlue;(deli_show);[location
+ 9].BackColor =
Color.White;(deli);.Sleep(Convert.ToInt32(Invoke(deli_track)));[location +
10].BackColor = Color.White;[location + 9].BackColor = Color.White;
}(deli_zamena);-;++;;'R':=
shortState;(graph == true)
{[location + 10].BackColor =
Color.SkyBlue;(deli_show);[location + 9].BackColor = Color.White;(deli);
}(deli_zamena);++; steps++;(graph ==
true).Sleep(Convert.ToInt32(Invoke(deli_track))); break;
}
}void заполнитьToolStripMenuItem_Click(object
sender, EventArgs e)
{dialog = new
OpenFileDialog();.InitialDirectory = "D:\\";.Filter = "Text
documents (*.txt*)|*.txt*";.RestoreDirectory = true;(dialog.ShowDialog()
== DialogResult.OK)
{
{.OpenFile();.Text =
File.ReadAllText(dialog.FileName);(int j = 0; j < textBox1.Lines.Length;
j++)
{(textBox1.Lines[j].Equals(""));[0]
= Splited(textBox1.Lines[j])[0];[1] =
Splited(textBox1.Lines[j])[2];.Add(keyv[0], keyv[1]);
}= Splited(textBox1.Lines[0])[2];
}(ArgumentException ec)
{.Show(ec.Message, "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error); textBox4.Text = "";
}
}
}String[] Splited(String str)
{delimeter = "->";[]
first = new String[3];= str.Split(delimeter.ToCharArray());first;
}void button3_Click(object sender,
EventArgs e)
{(textBox3.Text.Equals("")
|| textBox2.Text.Equals(""))
{ MessageBox.Show("Машина
Тьюринга
не
запущена!");
return; }(textBox3.Text.Equals("qz"))
{ MessageBox.Show("Машина
Тьюринга
завершила
свою
работу!");
return; }(flag == true)
{(okras == null)
{.Show("Работа машины не начата.");
return;
}(okras.IsAlive == true)
{.Suspend();= false;
}.Show("Работа
машины
завершена.");
}
{.Resume();= true;
}
}void button4_Click(object sender,
EventArgs e)
{[0] = 12; index = 0;
button2.Enabled = true;.WriteLine("Листинг
машины
Тьюринга:");.WriteLine("");.WriteLine("Исходное
слово
- " + textBox2.Text);.WriteLine("");(textBox3.TextLength == 0)
{ MessageBox.Show("Введите
состояние.",
"Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error); return; }pattern =
"\\bq((\\d\\d)|(\\d))\\b";rgx = new Regex(pattern);isMatch =
rgx.Match(textBox3.Text);(isMatch.Value == "")
{.Show("Состояние
введено
неверно.",
"Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error); return;
}(int j = 0; j < 50; j++)[j].Text
= "~"; location = 0;template = textBox2.Text;= textBox2.TextLength;=
textBox3.Text + state.Remove(0, state.Length - 2);i = 0;(i <
textBox2.TextLength)
{[i + 10].Text =
Convert.ToString(template[i]);++;
}
}void button5_Click(object sender,
EventArgs e)
{deli = new TheDelegate(State);enbl
= new TheDelegate(Button2Enabled);= state.Remove(state.Length - 2,
2);(shortState.Equals("qz"))
{.Show("Машина
Тьюринга
завершила
свою
работу.",
"Сообщение",
MessageBoxButtons.OK, MessageBoxIcon.Information);=
"qz";(deli);(enbl);[location + 10].BackColor =
Color.SkyBlue;[location + 9].BackColor = Color.White;;
}
{(mtstates[String.Concat(shortState
+ ribbon[location + 10].Text)], shortState);
}(Exception ex)
{.Show(ex.Message, "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error);.Text = ""; Invoke(enbl);
}
}void StepByStep(String state,
String shortState)
{deli = new
TheDelegate(State);deli_zamena = new TheDelegate(Replace);deli_show = new
TheDelegate(ShowState);.state = state;();(state[state.Length - 1])
{'L':= shortState;[location +
10].BackColor = Color.SkyBlue;(deli_show);(deli_zamena);[location +
9].BackColor = Color.White;[location + 11].BackColor = Color.White;(deli);-;
steps++;;'R':= shortState;[location + 10].BackColor =
Color.SkyBlue;(deli_show);(deli_zamena);[location + 9].BackColor =
Color.White;[location + 11].BackColor = Color.White;(deli);++; steps++;;
}
}void textBox2_KeyPress(object
sender, KeyPressEventArgs e)
{
{str =
e.KeyChar.ToString();(System.Text.RegularExpressions.Regex.IsMatch(str,
@"[^0-1\b]$"))
{.Handled = true;
}
}
}void textBox3_KeyPress(object
sender, KeyPressEventArgs e)
{
{str =
e.KeyChar.ToString();(System.Text.RegularExpressions.Regex.IsMatch(str,
@"[^\bq\d]$"))
{.Handled = true;
}
}
}void trackBar1_Scroll(object
sender, EventArgs e)
{.SetToolTip(trackBar1, "Скорость
работы
МТ.
Текущая
скорость
- " + trackBar1.Value.ToString() + " мс");
}wh;void button1_Click(object
sender, EventArgs e)
{[0] = 12;= "q00R"; index
= 0;(textBox5.TextLength == 0)
{ MessageBox.Show("Введите
длину
слова
(в
пределах
разумного).",
"Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error); return; }r =
Convert.ToInt32(textBox5.Text); WordLength = r;= new WordGenerator(0, r,
"01");pamd = new ParamDelegate(ProgressBarRender);progress =
0.0;progr = 100.00 / r;.Value = 0;(true)
{(int i = 0; i < 50; i++)
{[i].Text = "~";
}= "q0";p = 0;
{temp = wh.NextWord(ref
p);(!temp.Equals(""))
{(temp.Length > RandomWordLength)
{++; pamd(progress);= progress +
progr;
}(int i = 0; i < temp.Length;
i++)
{[i + 10].Text = temp[i].ToString();
}_flag = false;= "q00R";(progress);_Label();(steps
> max[index])[index] = steps;= 0;_flag = true;= temp.Length;
}
}(Exception ec)
{ RandomWordLength = 0; ;
GraphicRender(); return; }(int i = 0; i < 50; i++)
{[i].Text = "~";
}
}
}void button6_Click(object sender,
EventArgs e)
{(int i = 0; i < index+1; i++)
{.Show(max[i].ToString());
}
}void ProgressBarRender(double a)
{.Value =
Convert.ToInt32(Math.Round(a));
}void
GraphicRender(){.Series.Clear();mainGrapgh = new Series();.ChartType =
SeriesChartType.Line;.Series.Add(mainGrapgh);.Series[0].Color = Color.Red;.Name
= "ГС";[]
points = new Point[index + 1];(int i = 0; i < index + 1; i++)
{[i] = new Point(i,
chart1.Size.Height + max[i]);.Series[0].Points.AddXY(i,max[i]);(i % 3 == 0)
{.Series[0].Points[i].MarkerColor =
Color.ForestGreen;.Series[0].Points[i].MarkerStyle =
MarkerStyle.Circle;.Series[0].Points[i].MarkerSize = 3;
}.Series[0].Points[i].Label =
max[i].ToString();
}
}void chart1_Click(object sender,
EventArgs e)
{
График graph = new
График();.Show();
}void Form1_FormClosing(object
sender, FormClosingEventArgs e)
{.Close();.Exit(0);
}void textBox5_KeyPress(object
sender, KeyPressEventArgs e)
{
{str =
e.KeyChar.ToString();(System.Text.RegularExpressions.Regex.IsMatch(str,
@"[^\b\d]$"))
{.Handled = true;
}
}
}
}
//Дополнительная форма. Содержит: построение
большого графика
//График.cs
using
System;System.Collections.Generic;System.ComponentModel;System.Data;System.Drawing;System.Windows.Forms.DataVisualization.Charting;System.Linq;System.Text;System.Windows.Forms;TuringMachine
{partial class График
: Form
{График()
{();(ref Form1.max);
}RenderGraph(ref Int32[] max)
{i = 0;.Series.Clear();mainGrapgh =
new Series();highGrapgh = new Series();lowGraph = new Series();lowGraph2 = new
Series();.ChartType = SeriesChartType.Line;.ChartType =
SeriesChartType.Point;.ChartType = SeriesChartType.Point;.ChartType =
SeriesChartType.Point;.Series.Add(mainGrapgh);.Series.Add(highGrapgh);.Series.Add(lowGraph);.Series.Add(lowGraph2);.Name
= "2(n^2)+16n +15"; highGrapgh.Color = Color.Gray;.Name = "T(n)";
mainGrapgh.Color = Color.Red;.Name = "0,5(n^2)+2n+13"; lowGraph.Color
= Color.SkyBlue;.Name = "0,5(n^2)+5n+6"; lowGraph2.Color =
Color.Gold;(max[i] != 0) i++;.Refresh();[] points = new Point[i];lowgraph2 = 1;
int lowgraph = 0;highgraph = 0; int lowPoint = 0; int low2Point = 0;(int j = 0;
j < i; j++)
{[j] = new
Point(j,max[j]);.Series[0].Points.AddXY(j, max[j]);.Series[0].Points[j].Label =
max[j].ToString();.Series[0].Points[j].MarkerColor =
Color.ForestGreen;.Series[0].Points[j].MarkerSize = 10;.Series[0].Points[j].MarkerStyle
= MarkerStyle.Circle;(j % 3 == 0)
{.Series[1].Points.AddXY(j, 2 *
Math.Pow(j, 2)+16*j+12);.Series[1].Points[highgraph].MarkerColor =
Color.Gray;.Series[1].Points[highgraph].MarkerSize =
7;.Series[1].Points[highgraph].MarkerStyle = MarkerStyle.Circle;++;
}(lowgraph < j)
{.Series[2].Points.AddXY(j, 0.5*
Math.Pow(j, 2) + 2 * j + 13);.Series[2].Points[lowPoint].MarkerColor =
Color.SkyBlue;.Series[2].Points[lowPoint].MarkerSize =
7;.Series[2].Points[lowPoint].MarkerStyle = MarkerStyle.Circle;++;lowgraph =
lowgraph + 3;
}(lowgraph2 < j)
{.Series[3].Points.AddXY(j, 0.5 *
Math.Pow(j, 2) + 5 * j + 6);.Series[3].Points[low2Point].MarkerColor =
Color.Gold;.Series[3].Points[low2Point].MarkerSize =
7;.Series[3].Points[low2Point].MarkerStyle = MarkerStyle.Circle;Point++;=
lowgraph2 + 3;
}
}
}void сохранитьКакToolStripMenuItem_Click(object
sender, EventArgs e)
{dialog = new
SaveFileDialog();.InitialDirectory = "D:\\";.Filter = "Image
(*.jpg*)|*.jpg*";.RestoreDirectory = true;(dialog.ShowDialog() ==
DialogResult.OK)
{
{.SaveImage(dialog.FileName,
ChartImageFormat.Jpeg);
}(ArgumentException ec)
{.Show(ec.Message, "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error);;
}
}
}
}
}
//Дополнительный клас. Содержит: генератор всех
слов языка
using System;System.Collections.Generic;System.Linq;System.Text;TuringMachine
{WordGenerator
{
/// <summary>
/// Минимальная
длина
слова
/// </summary>int minlength;
/// <summary>
/// Текущая длина слова
/// </summary>
public int curlength;
/// <summary>
/// Максимальная
длина
слова
/// </summary>
int maxlength;
/// <summary>
/// Алфавит в котором необходимо генерировать
слова
/// </summary>string alphabet;
/// <summary>
/// Признак возможности генерации слова
/// </summary>
public bool CanGenerate = true;
/// <summary>
/// Сгенерированная комбинация
/// </summary><int> X;
/// <summary>
/// Пустой
конструктор
/// </summary>WordGenerator()
{
}
/// <summary>
/// Конструктор объекта для генерации
/// </summary>
/// <param
name="minlength">Минимальная
длина</param>
/// <param
name="maxlength">Максимальная
длина</param>
/// <param
name="alphabet">Алфавит
для
генерации
слов</param>WordGenerator(int
minlength,int maxlength, string alphabet)
{(minlength >= 0 & maxlength
>= minlength)
{.minlength = this.curlength =
minlength;.maxlength = maxlength;
}= true;.alphabet = alphabet;= new
List<int>(minlength);(int i = 0; i < minlength; i++)
X.Add(0);
}
/// <summary>
/// Генерация новой комбинации
/// </summary>void Next()
{i = 0;(i < X.Count && i
>= 0 && X[i] == alphabet.Length - 1)
{[i] = 0;++;
}(i < X.Count && i >=
0)
{[i]++;= true;
}= false;
}string NextWord(ref int variant)
{Word =
"";.WriteLine(curlength+" "+maxlength);(curlength <=
maxlength)
{(CanGenerate)
{<char> str = new
List<char>(X.Count);(int i = 0; i < X.Count; i++).Add(alphabet[X[i]]);=
new String(str.ToArray());++;();
}
{++;= new
List<int>(curlength);(int i = 0; i < curlength; i++).Add(0);= true;
}
}
{null;
}Word;
}
}
}
Приложение Е
Экранные формы
В данном разделе приведены экранные формы
разработанной программы.
Рисунок Е.1 - Окно построения
графика в виде мини-эскиза
Рисунок Е.2 - Процесс обработки
слова машиной
Рисунок Е.3 - Обработанное слово
Рисунок Е.4 - Сохранение графика временной
сложности