Математическая логика и теория алгоритмов

Постановка задачи и построение модели алгоритма, описание и доказательство его правильности. Описание переменных программы и расчет вычислительной сложности. Использование одномерного массива размерности, совпадение начального и конечного результата.

Рубрика Математика
Вид реферат
Язык русский
Дата добавления 30.10.2010
Размер файла 15,5 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Математическая логика и теория алгоритмов

Постановка задачи. Перечислить все способы расстановки n ферзей на шахматной доске n на n, при которых они не бьют друг друга

Построение модели. Очевидно, на каждой из n горизонталей должно стоять по ферзю. Будем называть k-позицией (для k = 0, 1,...,n) произвольную расстановку k ферзей на k нижних горизонталях (ферзи могут бить друг друга). Нарисуем "дерево позиций": его корнем будет единственная 0-позиция, а из каждой k-позиции выходит n стрелок вверх в (k+1)-позиции. Эти n позиций отличаются положением ферзя на (k+1)-ой горизонтали. Будем считать, что расположение их на рисунке соответствует положению этого ферзя: левее та позиция, в которой ферзь расположен левее

Дерево позиций для n = 2

Данное дерево представлено только для наглядности и простоты представления для n=2

Среди позиций этого дерева нам надо отобрать те n-позиции, в которых ферзи не бьют друг друга. Программа будет "обходить дерево" и искать их. Чтобы не делать лишней работы, заметим вот что: если в какой-то k-позиции ферзи бьют друг друга, то ставить дальнейших ферзей смысла нет. Поэтому, обнаружив это, мы будем прекращать построение дерева в этом направлении

Точнее, назовем k-позицию допустимой, если после удаления верхнего ферзя оставшиеся не бьют друг друга. Наша программа будет рассматривать только допустимые позиции

Описание алгоритма. Разобьем задачу на две части: (1) обход произвольного дерева и (2) реализацию дерева допустимых позиций

Сформулируем задачу обхода произвольного дерева. Будем считать, что у нас имеется Робот, который в каждый момент находится в одной из вершин дерева. Он умеет выполнять команды:

вверх_налево (идти по самой левой из выходящих вверх стрелок)

вправо (перейти в соседнюю справа вершину)

вниз (спуститься вниз на один уровень)

вверх_налево

вправо

вниз

и проверки, соответствующие возможности выполнить каждую из команд, называемые "есть_сверху", "есть_справа", "есть_снизу" (последняя истинна всюду, кроме корня). Обратите внимание, что команда "вправо" позволяет перейти лишь к "родному брату", но не к "двоюродному"

Будем считать, что у Робота есть команда "обработать" и что его задача - обработать все листья (вершины, из которых нет стрелок вверх, то есть где условие "есть_сверху" ложно). Для нашей шахматной задачи команде обработать будет соответствовать проверка и печать позиции ферзей

Доказательство правильности приводимой далее программы использует такие определения. Пусть фиксировано положение Робота в одной из вершин дерева. Тогда все листья дерева разбиваются на три категории: над Роботом, левее Робота и правее Робота. (Путь из корня в лист может проходить через вершину с Роботом, сворачивать влево, не доходя до нее и сворачивать вправо, не доходя до нее.) Через (ОЛ) обозначим условие "обработаны все листья левее Робота", а через (ОЛН) - условие "обработаны все листья левее и над Роботом"

Нам понадобится такая процедура:

procedure вверх_до_упора_и_обработать

{дано: (ОЛ), надо: (ОЛН)}

begin

{инвариант: ОЛ}

while есть_сверху do begin

вверх_налево

end

{ОЛ, Робот в листе}

обработать;

{ОЛН}

end;

Основной алгоритм:

дано: Робот в корне, листья не обработаны

надо: Робот в корне, листья обработаны

{ОЛ}

вверх_до_упора_и_обработать

{инвариант: ОЛН}

while есть_снизу do begin

if есть_справа then begin {ОЛН, есть справа}

вправо;

{ОЛ}

вверх_до_упора_и_обработать;

end else begin

{ОЛН, не есть_справа, есть_снизу}

вниз;

end;

end;

{ОЛН, Робот в корне => все листья обработаны}

Осталось воспользоваться следующими свойствами команд Робота (сверху записаны условия, в которых выполняется команда, снизу - утверждения о результате ее выполнения):

1. {ОЛ, не есть_сверху} обработать {ОЛН}

2. {ОЛ} вверх_налево {ОЛ}

3. {есть_справа, ОЛН} вправо {ОЛ}

4. {не есть_справа, ОЛН} вниз{ОЛН}

Теперь решим задачу об обходе дерева, если мы хотим, чтобы обрабатывались все вершины (не только листья)

Решение. Пусть x - некоторая вершина. Тогда любая вершина y относится к одной из четырех категорий. Рассмотрим путь из корня в y. Он может:

а) быть частью пути из корня в x (y ниже x);

б) свернуть налево с пути в x (y левее x);

в) пройти через x (y над x);

г) свернуть направо с пути в x (y правее x);

В частности, сама вершина x относится к категории в). Условия теперь будут такими:

(ОНЛ) обработаны все вершины ниже и левее;

(ОНЛН) обработаны все вершины ниже, левее и над

Вот как будет выглядеть программа:

procedure вверх_до_упора_и_обработать

{дано: (ОНЛ), надо: (ОНЛН)}

begin

{инвариант: ОНЛ}

while есть_сверху do begin

обработать

вверх_налево

end

{ОНЛ, Робот в листе}

обработать;

{ОНЛН}

end;

Основной алгоритм:

дано: Робот в корне, ничего не обработано

надо: Робот в корне, все вершины обработаны

{ОНЛ}

вверх_до_упора_и_обработать

{инвариант: ОНЛН}

while есть_снизу do begin

if есть_справа then begin {ОНЛН, есть справа}

вправо;

{ОНЛ}

вверх_до_упора_и_обработать;

end else begin

{ОЛН, не есть_справа, есть_снизу}

вниз;

end;

end;

{ОНЛН, Робот в корне => все вершины обработаны}

Приведенная только что программа обрабатывает вершину до того, как обработан любой из ее потомков. Теперь изменим ее, чтобы каждая вершина, не являющаяся листом, обрабатывалась дважды: один раз до, а другой раз после всех своих потомков. Листья по-прежнему обрабатываются по разу:

Под "обработано ниже и левее" будем понимать "ниже обработано по разу, слева обработано полностью (листья по разу, остальные по два)". Под "обработано ниже, левее и над" будем понимать "ниже обработано по разу, левее и над - полностью"

Программа будет такой:

procedure вверх_до_упора_и_обработать

{дано: (ОНЛ), надо: (ОНЛН)}

begin

{инвариант: ОНЛ}

while есть_сверху do begin

обработать

вверх_налево

end

{ОНЛ, Робот в листе}

обработать;

{ОНЛН}

end;

Основной алгоритм:

дано: Робот в корне, ничего не обработано

надо: Робот в корне, все вершины обработаны

{ОНЛ}

вверх_до_упора_и_обработать

{инвариант: ОНЛН}

while есть_снизу do begin

if есть_справа then begin {ОНЛН, есть справа}

вправо;

{ОНЛ}

вверх_до_упора_и_обработать;

end else begin

{ОЛН, не есть_справа, есть_снизу}

вниз;

обработать;

end;

end;

{ОНЛН, Робот в корне => все вершины обработаны полностью}

Доказательство правильности алгоритма. Докажем , что приведенная программа завершает работу (на любом конечном дереве)

Доказательство . Процедура вверх_налево завершает работу (высота Робота не может увеличиваться бесконечно). Если программа работает бесконечно, то, поскольку листья не обрабатываются повторно, начиная с некоторого момента ни один лист не обрабатывается. А это возможно, только если Робот все время спускается вниз. Противоречие

Описание переменных и программа. Теперь реализуем операции с деревом позиций. Позицию будем представлять с помощью переменной k: 0..n (число ферзей) и массива c: array [1..n] of 1..n (c [i] - координаты ферзя на i-ой горизонтали; при i > k значение c [i] роли не играет). Предполагается, что все позиции допустимы (если убрать верхнего ферзя, остальные не бьют друг друга)

program queens;

const n = ...;

var k: 0..n;

c: array [1..n] of 1..n;

procedure begin_work; {начать работу}

begin

k := 0;

end;

function danger: boolean; {верхний ферзь под боем}

var b: boolean;

i: integer;

begin

if k <= 1 then begin

danger := false;

end else begin

b := false; i := 1;

{b <=> верхний ферзь под боем ферзей с номерами < i}

while i <> k do begin

b := b or (c[i]=c[k]) {вертикаль}

or (abs(c[i]-c[k])=abs(i-k)); {диагональ}

i := i+ 1;

end;

danger := b;

end;

end;

function is_up: boolean {есть_сверху}

begin

is_up := (k < n) and not danger;

end;

function is_right: boolean {есть_справа}

begin

is_right := (k > 0) and (c[k] < n);

end;

{возможна ошибка: при k=0 не определено c[k]}

function is_down: boolean {есть_снизу}

begin

is_up := (k > 0);

end;

procedure up; {вверх_налево}

begin {k < n}

k := k + 1;

c [k] := 1;

end;

procedure right; {вправо}

begin {k > 0, c[k] < n}

c [k] := c [k] + 1;

end;

procedure down; {вниз}

begin {k > 0}

k := k - 1;

end;

procedure work; {обработать}

var i: integer;

begin

if (k = n) and not danger then begin

for i := 1 to n do begin

write ('<', i, ',' , c[i], '> ');

end;

writeln;

end;

end;

procedure UW; {вверх_до_упора_и_обработать}

begin

while is_up do begin

up;

end

work;

end;

begin

begin_work;

UW;

while is_down do begin

if is_right then begin

right;

UW;

end else begin

down;

end;

end;

end

Емкостная сложность:

В программе используется одномерный массив размерности n, поэтому объём входа и объём выхода совпадают и равны n. Количество пременных равно 3(i,b,k) + 1(const n), т.е. объём промежуточных данных равен 4

С(n)=n+4

Временная сложность:

Если рассматривать обработку каждого листа, без проверки на пути к нему, то временная сложность

T(n) = n 0 +n 1 +n 2 +n 3 +…+n n

Но в случае, когда каждая вершина проверяется, временная сложность. И это тем вернее, чем больше n. Данный вывод получен на основе приведённых ниже статистических данных:

Тестирование. Построенная по описанному алгоритму программа при различных n выдаёт следующие данные:

Т.е. количество расстановок равно 2. Ниже приведена таблица зависимости от n количества решений (R)

Список литературы

1. Кузнецов О.П. Адельсон-Вельский Г.М. Дискретная математика для инженера. - М.: Энергоатомиздат, 1988.

2. Евстигнеев В.А. Применение теории графов в программировании. - М.:Наука, 1984.

3. Основной алгоритм находился на BBS “Master of Univercity” в файле shen.rar в файловой области “Bardak” (тел. 43-27-03; время работы 21.00 - 7.00; FTN адрес - 2:5090/58).


Подобные документы

  • Нахождение минимального пути от фиксированной до произвольной вершины графа с помощью алгоритма Дейкстры, рассмотрение основных принципов его работы. Описание блок-схемы алгоритма решения задачи. Проверка правильности работы разработанной программы.

    курсовая работа [495,4 K], добавлен 19.09.2011

  • Графическая интерпретация множеств и операций над ними. Математическая логика, булева алгебра. Совершенная конъюнктивная нормальная форма. Равносильные формулы и их доказательство. Полнота системы булевых функций. Логика предикатов, теория графов.

    лекция [253,7 K], добавлен 01.12.2009

  • Математическая логика (бессмысленная логика), логика "здравого смысла" и современная логика. Математические суждения и умозаключения, их направления. Математическая логика и "Здравый смысл" в XXI веке. Неестественная логика в основаниях математики.

    реферат [32,2 K], добавлен 21.12.2008

  • Основные определения математической логики, булевы и эквивалентные функции. Общие понятия булевой алгебры. Алгебра Жегалкина: высказывания и предикаты. Определение формальной теории. Элементы теории алгоритмов, рекурсивные функции, машина Тьюринга.

    курс лекций [651,0 K], добавлен 08.08.2011

  • Описание метода потенциалов Математическая постановка задачи об оптимальных перевозках. Метод решения задачи об оптимальных перевозках средствами Ms Excel. Постановка параметрической транспортной задачи, ее математическое и компьютерное моделирование.

    курсовая работа [802,5 K], добавлен 21.10.2014

  • Построение таблицы истинности. Доказательство истинности заключения путём построения дерева доказательства или методом резолюции. Выполнение различных бинарных операций. Построение графа вывода пустой резольвенты. Основные правила исчисления предикатов.

    курсовая работа [50,7 K], добавлен 28.05.2015

  • Свободное падение тела с учетом сопротивления среды. Зависимость перемещения и скорости падения от времени. Формулировка математической модели и ее описание. Описание программы исследования с помощью пакета Simulink. Решение задачи программным путем.

    курсовая работа [1,2 M], добавлен 21.03.2011

  • Форма для ввода целевой функции и ограничений. Характеристика симплекс-метода. Процесс решения задачи линейного программирования. Математическое описание алгоритма симплекс-метода. Решение задачи ручным способом. Описание схемы алгоритма программы.

    контрольная работа [66,3 K], добавлен 06.04.2012

  • Простейшая разностная схема для задачи Дирихле: построение, аппроксимация и устойчивость. Описания метода установления. Анализ алгоритмов, реализующих метод установления: решение в виде конечного ряда Фурье, схема установления и переменных направлений.

    курсовая работа [323,4 K], добавлен 25.11.2011

  • Составление таблицы значений функции алгебры логики и нахождение всех существенных переменных. Связный ориентированный и взвешенный граф. Построение функции полиномом Жегалкина. Текст программы для алгоритма Дейкстры. Определение единиц и нулей функции.

    контрольная работа [43,2 K], добавлен 27.04.2011

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.