Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Графы. Модели вычислений. Структуры данных

..pdf
Скачиваний:
231
Добавлен:
01.05.2014
Размер:
2.53 Mб
Скачать

Префиксная форма:

Pref (H1): x y [E(x) P(x) [R(x, y) &D(y)]],

Pref (H2): x y [E(x) &M(x) &[R(x, y) M(y)]], Pref (H3): x [M(x) → ¬P(x)],

Pref (C): x [M(x) &D(x)].

Сколемовская форма:

Sk (H1): x [E(x) P(x) [R(x, f (x)) &D(f (x))]], Sk (H2): y [E(a) &M(a) &[R(a, y) M(y)]],

Sk (H3): x [M(x) → ¬P(x)],

Sk (¬C): x [¬M(x) ¬D(x)].

Клаузальная форма (опускаем кванторы общности, а бескванторные части приводим к КНФ и из каждого сомножителя получаем клаузу):

Cla (H1): [¬E(x) P(x) R(x, f (x)] &[¬E(x) P(x) D(f (x)) ], Cla (H2): M(a) &E(a) &[¬R(a, y) M(y)],

Cla (H3): ¬P(x) ¬M(x),

Cla (C): ¬M(x) ¬D(x).

Доказательство с использованием правила резолюции

1.

¬E(x) P(x) R(x, f (x)

– из гипотезы H1,

2.

¬E (x) P(x) D(f (x))

– из гипотезы H1,

3.

M(a),

– из гипотезы H2,

4.

E(a),

– из гипотезы H2,

5.

¬R(a, y) M(y),

– из гипотезы H2,

6.

¬P(x) ¬M(x),

– из гипотезы H3,

7.

¬M(x) ¬D(x),

– из заключения C,

8.

P(a) R(a, f (a),

– из 1, 4 с помощью подстановки (x/a),

9.

P(a) D(f (a)),

– из 2, 4 с помощью подстановки (x/a),

10. ¬P(a),

– из 3, 6 с помощью подстановки (x/a),

171

11.

D(f (a)),

– из 9, 10,

12.

¬M(f (a))

– из 7, 11 с помощью подстановки (x/f (a)),

13.

R(a, f (a),

– из 8, 10,

14.

M(f (a)),

– из 5, 13 с помощью подстановки (y/f (a)),

15.

 

– из 12, 14

Пример 2 . Рассмотрим предикаты с интерпретацией: F(x, y) x является отцом для y,

S(x, y) x, y – дети одного отца, M(x) x – мужчина,

B(x, y) x брат для y,

В качестве аксиом рассмотрим формулы

A1: x y [F(x, y) M(x)],

A2: x y w [F(x, y) &F(x, w) S(y, w)],

A3: x y [S(x, y) &M(x) B(x, y)].

Пусть из интерпретации известны факты

A4: F(‘Иван’, ‘Харитон’),

A5: F(‘Иван’, ‘Василий’),

A6: F(‘Василий’, ‘Елена’).

Вопрос: «Есть ли брат у Харитона?» – на языке предикатов записывается как

A7: z B(z, ‘Харитон’)?

Доказательство

1.¬F(x, y) M(x)

2.¬F(x, y) ¬F(x, w) S(y, w)

3.¬S(x, y) ¬M(x) B(x, y)

4.F(‘Иван’, ‘Харитон’)

5.F(‘Иван’, ‘Василий’)

6.F(‘Василий’, ‘Елена’)

7.¬B(z, ‘Харитон’)

8.¬F(‘Иван’, w) S(‘Василий’, w)

из формулы A1,

из формулы A2,

из формулы A3,

формула A4,

формула A5,

формула A6,

отрицание запроса A7,

из 2, 5, подстановка

(x/‘Иван’, y/‘Василий’),

9. S(‘Василий’, ‘Харитон’)

– из 4, 8, подстановка

 

(w/‘Харитон’),

172

10.

M(‘Василий’)

– из 6, 1, подстановка

 

 

(x/‘Василий’, y/‘Елена’),

11.

¬S(‘Василий’, y) B(‘Василий’,y) – из 10, 3, подстановка

 

 

(x/‘Василий’),

12.

B(‘Василий’, ‘Харитон’)

– из 9, 11, подстановка

 

 

(y/‘Харитон’),

13.

 

– из 12, 7, подстановка

 

 

(z/‘Василий’)

Фактически мы не только получили ответ на наш запрос, но и подтвердили его конкретным значением переменной z. Приведенный вывод можно модифицировать, если ввести предикат answer(z) и вместо цели «7. ¬B(z, ‘Харитон’)» поставить новую цель

7. ¬B(z, ‘Харитон’) answer(z). Тогда шаг 13 превратится в 13. 13. answer(‘Василий’) – из 12, 7, подстановка (z/‘Василий’).

Упражнение

Рассмотрите вывод, в котором первые 7 формул являются посылками. Для остальных формул выпишите пояснения к применению правила резолюции.

1.¬A(z),

2.A(x) ¬P(x) ¬Q(x, y),

3.A(x) ¬R(y) ¬Q(y, x),

4.P(a),

5.Q(b, c),

6.R(a),

7.R(b),

8.¬P(z) ¬Q(z, y),

9.¬Q(a, y),

10.¬R(y) ¬Q(y, z),

11.¬Q(a, z),

12.¬Q(b, z),

13.

6.4. Элементы языка Пролог

Основным элементом языка Пролог является терм. Термы строятся из переменных, атомов, чисел и функторов с использованием круглых скобок.

173

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

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

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

Функтор синтаксически совпадает с атомом.

Терм – это либо переменная, либо атом, либо число, либо выражение вида

f (t1, t2, …, tk),

где f – функтор, а t1, t2, …, tk – термы.

Для некоторых специальных функторов, например знаков арифметических операций, отношений сравнения и других, в Прологе, как в традиционной математике, используется инфиксная форма записи. Например, выражение X + 1 рассматривается как терм с функтором + и двумя аргументами X и 1.

Среди термов ввиду особой важности выделяются термы для представления списков. Канонически список представляется двухместным термом, первым аргументом которого является головной элемент списка, а вторым – его хвост, то есть список, полученный из исходного удалением головного элемента. Функтором в такой записи часто используется символ точка. Альтернативным представлением списка является выражение вида [t1, t2, …, tk] или [t | L], где t – головной элемент, а L – хвост списка. Допустимо также выражение вида [t1, t2, …, tk | L].

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

Подстановкой называется набор пар θ = (x1/t1, x2/t2, …, xn/tn), где x1, x2, …, xn – переменные, а t1, t2, …, tn – термы.

Через Eθ обозначим результат подстановки термов t1, t2, …, tn в вы-

174

ражение E вместо переменных x1, x2, …, xn .

Пусть π = (y1/u1, y2/u2, …, ym/um) – еще одна подстановка. Композиция θπ двух подстановок θ и π определяется следующим образом

E(θπ) = (Eθ)π.

Подстановка θπ может быть вычислена следующим образом. Составим из подстановок θ и π последовательность

(x1/t1π, x2/t2π, …, xn/tnπ, y1/u1, y2/u2, …, ym/um)

ипроведем следующие две операции:

1.Если некоторое yi совпадает с некоторым xj, то вычеркиваем пару yi /ui.

2.Если tiπ = xi, то вычеркиваем пару xi/tiπ.

Пример. Пусть θ = (x/f (y), y/z), π = (x/a, y/b, z/y). Составим последовательность

(x/f (y)π, y/zπ, x/a, y/b, z/y) = (x/f (b), y/y, x/a, y/b, z/y)

и по первому правилу вычеркиваем пары x/a и y/b, затем по второму правилу – пару y/y. В результате получим

θπ = (x/f (b), z/y).

Подстановка θ называется унификатором термов E1, E2, если E1θ = = E2θ. Наиболее общим унификатором термов E1, E2 называется под-

становка σ, такая, что любой другой их унификатор θ представляется в виде θ = σπ.

Пример. Для термов P(a, y), P(x, f (b)) унификатором будет подстановка

(x/a, y/f (b)).

Будет ли она наиболее общим унификатором?

Пример. Для термов P(a, x, f (g(y))) и P(z, f (z), f (u)) наиболее общим унификатором будет подстановка (z/a, x/f (a), u/g(y)). Результатом унификации будет терм P(a, f (a), f (g(y))).

175

Часть 3. СТРУКТУРЫ ДАННЫХ

Введение

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

– обычные арифметические операции.

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

ввести в рассмотрение пустое множество;

включить элемент в множество;

исключить элемент из множества;

проверить, пусто ли рассматриваемое множество:

узнать, сколько элементов в рассматриваемом множестве.

Эти операции с некоторой точки зрения можно считать элементарными и до известной поры не думать о способе их реализации исполнителем. В таких случаях говорят, что мы имеем дело с абстрактным типом данных.

176

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

ио реализации операций над ними доступными средствами.

Внастоящее время большинство алгоритмов проектируется для использования в устройствах, обладающих адресуемой памятью. Каждый элемент информации, размещенный в такой памяти, занимает определенную позицию. По известной позиции элемента в такой памяти доступ к нему осуществляется за некоторую условную единицу времени, зависящую только от типа получаемой информации, фактически – от физического размера ячейки памяти или от количества таких ячеек, предназначенных для ее хранения, но не от ее конкретного содержания. Более того, позиции элементов сами могут быть элементами информации, с которыми могут производиться некоторые операции, что позволяет использовать так называемую косвенную адресацию. Наличие косвенной адресации позволяет поручить программной системе или разрабатываемой прикладной программе поиск свободных участков памяти для размещения новых элементов информации и запоминание их адресов с последующим их использованием для доступа к информации.

Информация, размещенная в адресуемой памяти, приобретает новые свойства. Элемент информации характеризуется не только своим содержанием, но и адресом, то есть местом расположения в памяти. Два элемента данных, соседних в некотором содержательном смысле, не обязательно будут располагаться в соседних ячейках памяти. Они могут оказаться в «непредвиденных» местах. Проектируя программную реализацию алгоритма, необходимо проектировать и способ расположения в памяти обрабатываемой информации.

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

177

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

вприемлемое время.

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

Во многих задачах исходные данные представляют собой так называемые взвешенные множества. Взвешенным называется множество, каждому элементу которого поставлено в соответствие в качестве веса некоторое число. Часто используемыми операциями с такими множествами являются поиск элемента с минимальным весом, вставка нового элемента со своим весом, удаление элемента и некоторые другие. Для быстрого выполнения таких операций разработаны так называемые кучеобразные структуры данных.

Классы функций, используемые для оценки сложности алгорит-

мов. Все функции, используемые ниже для оценки сложности алгоритмов, считаются асимптотически неотрицательными функциями натурального аргумента, то есть неотрицательными начиная с некоторого значения

аргумента n.

Для асимптотических оценок сверху используется класс функций

Ο(g(n)) ={ f (n) : c > 0, n0 n > n0[0 f (n) c g(n)]}.

Для асимптотических оценок снизу используется класс функций

(g(n)) ={ f (n) : c > 0, n0 n > n0[0 c g(n) f (n)]}.

Для асимптотически точных оценок используется класс функций

Θ(g(n)) ={ f (n) : c1, c2 > 0, n0 n > n0[0 c1g(n) f (n) c2 g(n)]}.

Очевидно, справедливы следующие соотношения

Θ(g(n)) = Ο(g(n)) I(g(n)),

178

f (n) Ο(g(n)) g(n) ( f (n)).

Далее, предполагается знание стандартных функций, используемых при оценках сложности, таких, как полиномы, экспоненты, суперэкспоненты, логарифмы, суперлогарифмы, факториалы, числа Фибоначчи. Предполагается умение их сравнивать по скоростям роста.

Амортизационный анализ. Наряду с получением верхних и нижних оценок и оценок в среднем часто используются так называемые амортизационные оценки.

Амортизационный анализ применяется при оценке времени выполнения корректной последовательности, состоящей из n однотипных или разнотипных операций с некоторой структурой данных. Если верхнюю оценку времени выполнения одной операции умножить на n, получим верхнюю оценку выполнения всех n операций. Часто такая оценка бывает сильно завышенной. Иногда большое время выполнения очередной операции влечет малое время выполнения следующих операций. Более того, такая ситуация может создаваться искусственно, то есть при выполнении очередной операции мы можем готовить почву для более эффективного выполнения следующей. Поэтому возникает задача изучения асимптотического поведения гарантированной оценки для среднего времени выполнения одной операции.

При амортизационном анализе определяется некоторая так называемая учетная (амортизационная) стоимость одной операции, которая может быть как больше, так и меньше реальной стоимости конкретной операции. Но при этом для любой корректной последовательности операций фактическая суммарная длительность всех операций не должна превосходить суммы их учетных стоимостей. Зная учетную стоимость одной операции, верхнюю оценку времени выполнения последовательности из n операций можно получить, умножив ее на n.

Ниже рассмотрим три часто используемых метода амортизационного анализа: метод группировки, метод предоплаты и метод потенциалов.

Метод группировки. Предположим, что мы оценили сверху время выполнения последовательности из n операций, установив, что она не превосходит T(n), тогда величину T(n)/n объявим учетной стоимостью любой операции из рассматриваемой последовательности, независимо от ее длительности.

Метод предоплаты. В этом методе операции разных типов получают разные учетные стоимости, причем эти стоимости могут быть как больше, так и меньше фактических. Если учетная стоимость превосходит факти-

179

ческую, то разность между ними рассматривается как резерв на оплату в будущем тех операций, у которых учетная стоимость ниже реальной. Учетные стоимости должны выбираться так, чтобы в любой момент времени фактическая стоимость не превосходила суммы учетных стоимостей, то есть чтобы резерв оставался неотрицательным.

Метод потенциалов. Этот метод является обобщением метода предоплаты. Здесь резерв определяется функцией состояния структуры данных в целом. Эта функция называется потенциалом.

Общая схема метода такова. Пусть над структурой данных предстоит произвести n операций, и пусть Di – состояние структуры данных после i-й операции (D0 – исходное состояние). Потенциал представляет собой функцию φ из множества возможных состояний структуры данных в множество действительных чисел.

Пусть ci – реальная стоимость i-й операции. Учетной стоимостью i-й операции объявим число Ci, определяемое формулой

Ci = ci (Di) −φ(Di1)

как сумма реальной стоимости операции плюс приращение потенциала в результате выполнения этой операции. Тогда суммарная учетная стоимость всех операций равна

n

n

Ci = ci + φ(Dn ) − φ(D0 ).

i=1

i=1

Если нам удалось придумать функцию φ, для которой

φ(Dn ) ≥ φ(D0 ),

то суммарная учетная стоимость даст верхнюю оценку для реальной стоимости последовательности из n операций. Не ограничивая общности, можно считать, что

φ(D0 ) = 0.

Говоря неформально, если разность потенциалов

φ(Di ) −φ(Di1 )

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

Учетные стоимости и оценки реальной стоимости, рассчитанные с

180