Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
GOSY / 2 блок-все.pdf
Скачиваний:
68
Добавлен:
09.05.2015
Размер:
1.5 Mб
Скачать

Формула для числа сочетаний с повторениями:

H (m, n) = C(n + m − 1, n)

Когда распределяем 2 предмета в один ящик, то можно сказать, что помещаем в два ящика по одному предмету. Если мы добавим n-1 ящик, то любую комбинацию, при которой в ящиках по несколько предметов, можно представить в виде комбинации заполнения с помощью дополнительных ящиков по одному предмету. В результате необходимо величину m увеличить на n-1 и

задача будет сведена к задаче без повторений. Пример. Число различных бросаний двух одинаковых

кубиков равно Cˆ(6,2) = C72 = 21.

Разбиения

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

Пусть Β

= {B1 ,...., Bn }

есть разбиение множества Х из

m элементов на n подмножеств:

Bi X ,

n

Bi = X ,

Bi

¹ Æ , Bi Ç B j = Æ при

 

i= 1

 

i ¹

j

 

 

 

Подмножества Bi называются блоками разбиения.

Между разбиениями и отношениями эквивалентности существует взаимнооднозначное отношение. Если E1 и

E2 - два разбиения Х, то говорят, что разбиение E1 есть измельчение разбиения E2 , если каждый блок E2 есть

объединение блоков E1 .

Если k=2, упорядоченное разбиение множества М на два подмножества, имеющие соответственно m1 и m2

142

элементов, определяется сочетанием (без повторений) из n элементов по m1 или из n элементов по m2 ( m2 = n m1 ). Следовательно, число разбиений R(m1 , m2 ) равно

биноминальному коэффициенту Cnm1

 

=

Cnm2 . Таким

образом,

 

 

 

n!

 

 

 

n!

 

R(m ,m

2

) =

 

=

 

 

.

 

 

 

 

 

 

1

 

m1!(n m1 )!

 

 

m1!m2!

 

 

 

 

 

В общем

случае

число

 

 

R(m1 , m2 ,..., mk )

упорядоченных разбиений ( M1, M 2 ,..., M k ), для которых

M i

 

= mi , равно

n!

 

, а число

R(n, k)

 

 

m1!m2

!...mk !

 

 

 

 

 

упорядоченных разбиений на k подмножеств вычисляется по формуле

R(n,k) =

å R(m1,m2 ,...,mk ).

m1

+ ...+ mk , = n

mi

> 0

Числа R(m1 , m2 ,..., mk ) называются

полиномиальными коэффициентами, поскольку для всех a1 , a2 ,..., ak R справедливо соотношение

(a +

a

2

+ ... +

a

k

)n =

 

 

 

 

1

 

 

 

 

 

 

 

 

 

 

 

 

=

 

å

 

 

 

 

 

 

n!

 

 

a1m1 a2m2

...ak mk

 

 

 

= n m !m

!...m

!

m + ...+ m

k ,

 

 

1

 

 

 

1

 

 

2

k

 

 

 

 

mi

> 0

 

 

 

 

 

 

 

 

 

 

 

 

143

Пример. В студенческой группе, состоящей из 25 человек, при выборе старосты за выдвинутую кандидатуру проголосовали 12 человек, против – 10, воздержались – 3. Сколькими способами могло быть проведено такое голосование?

Пусть М – множество студентов в группе, M1 - множество студентов, проголосовавших за выдвинутую кандидатуру, M 2 - множество студентов, проголосовавших

против, M 3 - множество студентов, воздержавшихся от

голосования.

 

 

 

 

 

Тогда

 

M

 

= 25,

 

M1

 

= 12,

 

M 2

 

= 10

 

M 3

 

= 3,(M1 , M 2 , M 3 )

 

 

 

 

 

 

 

 

- упорядоченное разбиение множества M. Искомое число

R(12, 10, 3) равно 12!10!3!25! = 1487285800 .

Число Rˆ(m1,m2 ,...,mk ) разбиений исходного

множества M на k подмножеств

M1, M2 ,..., Mk ,

 

M i

 

= mi , неупорядоченных между

собой,

вычисляется

 

 

по формуле

 

 

n!

 

 

 

 

 

ˆ

 

 

 

,

 

 

 

,...,mk ) = m !...m !(1!)m1

 

 

 

 

R(m1,m2

...(n!)mk

 

 

 

 

1

k

 

 

а число всех возможных разбиений множества M на k подмножеств, неупорядоченных между собой, равно

å Rˆ (m1, m2 ,..., mk )

m1 + ...+ mk , = n mi > 0

Пример. Сколькими способами из группы в 25 человек можно сформировать 5 коалиций по 5 человек?

144

Пусть X – множество людей в группе, mi - число коалиций по i человек, где i=1,…25. Тогда по условиям

задачи

 

M

 

= 25, m5

= 5, mi

=

0,i {1,2,...,25} \ {5},

 

 

и, следовательно,

 

 

искомое

число будет равно

ˆ

 

25!

 

 

25!

 

R(0,0,0,0,5,0,...,0)

=

 

 

=

 

.

 

5!(5!)5

 

(5!)6

Теорема. Пусть S(n, k) – число разбиений множества n- X на k блоков. Тогда вычисление S(n, k) может быть выполнено рекурсивно на основе тождеств:

S(n, k = )S(n − 1, k − 1) + kS(n − 1, k),

если 0 < k < n, S(n, n) = 1, если n=0,

S(n,0) = 0 , если n>0.

Доказательство. Для доказательства рассмотрим множество всех разбиений n-X на k подмножеств.

Это множество можно представить двумя пересекающимися классами: тех разбиений, которые содержат одноэлементный блок {n}, и тех, которые его не содержат. В этом случае n содержится по крайней мере в двухэлементном блоке. Мощность первого класса равна

S(n − 1, k − 1) , т. е. такова, каково число разбиений

множества {1, 2, …,n-1} на k-1 блоков. Мощность второго класса равна kS(n − 1, k) , поскольку каждому разбиению

множества {1, 2, …,n-1} на k-1 блоков соответствует в этом классе ровно k разбиений, образованных добавлением элемента n поочередно к каждому блоку. Доказательство окончено.

Числа S(n, k) называются числами Стирлинга второго рода. Рассчитанные по формулам (3.31)-(3.33), они могут

145

быть представлены в виде треугольной таблицы – треугольника Стирлинга. Треугольник Стирлинга для значений n от 0 до 7 представлен в таблице.

Таблица

Числа Стирлинга второго рода

n

 

 

 

 

k

 

 

 

0

1

2

3

4

5

6

7

0

1

0

0

0

0

0

0

0

1

0

1

0

0

0

0

0

0

2

0

1

1

0

0

0

0

0

3

0

1

3

1

0

0

0

0

4

0

1

7

6

1

0

0

0

 

 

 

1

 

 

 

 

 

5

0

1

5

25

10

1

0

0

 

 

 

3

 

 

 

 

 

6

0

1

1

90

65

15

1

0

 

 

 

6

30

35

14

2

 

7

0

1

3

1

0

0

1

1

Числа Белла определяются как сумма всех разбиений от 0 до n блоков множества n-X:

X n = å kk = 0

S(n, k) . (3.34)

Первые восемь чисел Белла в таблице 3.2.

При посчете числа разбиений необходимо иметь в виду, что числа Белла растут очень быстро. Так, например, уже при n = 20 Bn = 51 724 158 235 372.

Таблица 3.2

n

 

 

Числа Белла

 

0

1

2

3

4

5

6

7

B

 

 

 

 

1

5

20

87

n

1

1

2

5

5

2

3

7

146

Разбиение чисел

Под разбиением числа n понимается его представление

в виде n =

x1 +

x2 + ... + xk (xi >

0 целое) . При

этом

порядок

слагаемых не

существенен, а

x1 ³

x2 ³

... ³ xk .

 

Суммы считаются эквивалентными, если они отличаются лишь порядком слагаемых.

Число разбиений числа n на k слагаемых будем обозначать P(n, k), число всех разбиений – P(n).

Очевидно, что

P(n) = å nk= 1 P(n,k),n > 0.

 

 

 

 

Разбиени

 

k

я n

P(n, k)

1

7

1

2

6 1

3

 

5 2

 

 

4 3

 

3

5 1 1

4

 

4 2 1

 

 

3 3 1

 

 

3 2 2

 

4

4 1 1 1

3

 

3 2 1 1

 

 

2 2 2 1

 

5

3 1 1 1 1

2

 

2 2 1 1 1

 

 

2 1 1 1 1 1

 

61

1 1 1 1 1 1

7

1

1

 

 

 

Рис. 3.8

 

147

Рассмотрим пример. Пусть необходимо получить все разбиения числа n=7. Это возможно сделать различными способами, показанными на рис. 3.8.

Разложение P(n) в сумму P(n, k) делает наглядной структуру разбиений числа n, однако вычисление значений P(n) непосредственно по формуле (3.36) не всегда возможно, поскольку сами значения P(n, k) заранее, как правило , не известны.

Для подсчета P(n) удобно воспользоваться функцией Q(m, n), значением которого является число способов представления целого m в виде суммы при условии, что каждое слагаемое не превосходит n. Число разбиений целого n равно Q(n, n)= P(n).

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

Q(m, n) = [(m = 1) (n = 1) → 1,

(m < n) → Q(m, m − 1), (m = n) → 1+ Q(m, m − 1),

(m > n) → Q(m, n − 1) + Q(m n, n)].

При исследовании свойств чисел P(n) могут также оказаться полезными диаграммы Феррерса. Диаграммы Феррерса состоит из k строк, соответствующих слагаемым разбиения, причем i-ая строка содержит последовательность из xi точек.

Например, разлагая 7 на четыре слагаемых, имеем одну из диаграмм Феррерса.

148

ì ·

· ·

 

ï

·

·

 

ï

7=3+2+1+1

kí

·

 

ï

 

 

ï

·

 

 

î

 

 

Каждому разбиению, изображенному диаграммой Феррерса соответствует сопряженное разбиение, которое получается заменой строк столбцами.

 

k

 

 

7=4+2+1

 

 

 

Непосредственно из определения диаграммы Феррерса следует, что число разбиений числа n на k слагаемых равно числу разбиений числа n с наибольшим слагаемым, равным k.

Получим алгоритм генерирования всех разбиений числа n.

Пусть n =

a1 +

a2 + ... + ak . Обозначим s ≤ n такое,

что

ì a

 

+ 1+ 1+

... + 1,k >

j

 

i

s =

ï

 

 

 

 

 

í

 

 

 

k −

j

 

,

 

ï

 

 

 

ai ,k <

j

 

 

î

 

 

 

 

где i =

max(m : am

>

1), j =

ai 1.

Для построения этого алгоритма достаточно заметить, что разбиение s’, непосредственно следующее за s, имеет вид

149

s'= å 1[s / j] j + (s mod j),

где символами [s/j] обозначено наибольшее целое, не превосходящее s/j.

При этом все элементы разбиения n : a1 , a2 ,...,ai− 1

являются общими как для s, так и для s’.

Инициация алгоритма осуществляется значениями i=1, ai=n, j=n-1, k=1.

Биноминальные коэффициенты

Сnk(число сочетаний) - это число способов выбрать k различных (т.е. без повторений) предметов из n различных (0<=k<=n), без учета порядка выбора. Они могут быть вычислены по следующим формулам:

Треугольник Паскаля и Бином Ньютона:

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

Cn+1k+1=Cnk+Cnk+1.

Давайте построим из чисел два бесконечных треугольника. В первом из них (см. рис. внизу слева) будем ставить единицы в самом верху и по краям каждом следующей строки, а каждое из остальных чисел будет равно сумме двух стоящих над ним слева и справа (этот треугольник называется треугольником Паскаля). Во втором (см. рис. внизу справа) будем последовательно выписывать значения Cnk, отводя по одной строке для каждого значения n и располагая в ней Cnk по возрастанию k. На самом деле эти треугольники одинаковы.

150

Равенство первых нескольких строчек, можно заметить, а дальше надо уже доказывать.

C00

 

C1

C1

 

 

 

0

1

 

 

 

C2

C2

C2

 

 

0

1

2

 

C3

C3

C3

 

C3

0

1

2

 

3

C4

C4

C4

C4

C4

0

1

2

3

4

Утверждение. Если строчки треугольника Паскаля и позиции в них нумеровать, начиная с нуля, то на k-м месте в n-й строке будет стоять значение Cnk (основное свойство треугольника Паскаля).

Доказательство: Индукция по n (см. лекцию "Индукция", если вы еще не знакомы с этим методом).

База: n=0 - действительно, C00=1 - как раз то, что стоит на верхушке треугольника Паскаля.

Переход: от n к n+1. Пусть в n-й строчке все числа уже равны значениям Cnk из n по соответствующим k. Рассмотрим n+1-ю строчку. На ее краях (нулевое и n+1-е места) стоят две единицы - и значения Cn+10 и Cn+1n+1 как раз равны 1. Далее, при всех k от 1 до n число, стоящее на k-м месте в n+1-й строке, равно сумме чисел, стоящих в n- й строке на k-1-м и k-м местах соответственно (т.е. как раз двух стоящих над ним - по принципу построения треугольника Паскаля). По предположению индукции, они равны Cnk-1 и Cnk, а их сумма тогда будет Cnk-1+Cnk, что как

раз равно Cn+1k, ч.т.д.

Для справки мы приводим здесь первые 11 строчек (с нулевой по 10-ю) треугольника Паскаля - их можно

151

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

 

 

1

1

 

 

 

 

 

1

2

1

 

 

 

1

3

3

1

 

 

 

1

4

6

4

1

 

1

5

10

10

5

 

1

1

6

15

20

15

6

1

Такие, казалось бы, чисто комбинаторные вещи, как

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

(a+b)

 

 

 

 

 

 

 

0=

 

 

 

1

 

 

(a+b)

 

 

 

 

 

 

 

a+b

 

 

1=

 

2

2

 

(a+b)

a +2ab+b

 

 

3

+3a

2

b+3ab

2

2

=

a

 

 

 

 

 

+b3

 

 

(a+b)

 

 

 

 

 

 

 

3=

 

 

 

 

 

 

 

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

152

(a+b)n=an+Cn1an-1b+Cn2an-2b2+...+Cnn-1a1bn-1+bn.

Можно доказать эту формулу по индукции, как и основное свойство треугольника Паскаля. Приведем более простое объяснение:

(a+b)n=(a+b)(a+b)...(a+b) (n скобок). Раскрывая скобки, получаем в отдельных слагаемых произведения n букв, каждая из которых - a или b, т.е. an-kbk при каком-то k от 0 до n. Докажем, что для каждого такого k число таких слагаемых - ровно Cnk, откуда, приведя подобные, и получаем формулу бинома. Но это правда: an-kbk получается путем взятия a из k скобок и b из n-k оставшихся; разные такие слагаемые получаются путем разного выбора этих самых k скобок, а k скобок из n можно выбрать как раз Cnk способами, ч.т.д.

Именно из-за бинома Ньютона числа Cnk часто называют биномиальными коэффициентами.

Следствие 1

åm C(m, n) = 2m

n= 0

Доказательство. Заметим, что 2n=(1+1)n и раскроем по формуле бинома Ньютона (при a=b=1). Получим 1+Cn1+Cn2+...+Cnn-1+1 - с учетом того, что Cn0=Cnn=1, это как раз сумма из условия, ч.т.д.

Следствие 2

åm (1)n C(m, n) = 0 (доказать самостоятельно, при

n= 0

доказательстве использовать формулу бинома Ньютона при a=1, b=-1).

Свойства биномиальных коэффициентов

153

Биномиальные коэффициенты обладают целым рядом замечательных свойств.

Теорема

1. åm nC(m, n) = m2m− 1 ,

n= 0

2. C(m + n,k) = åk C(m,i)C(n, k i) .

i= 0

Рекуррентные соотношения.

Рекуррентным соотношением, рекуррентным уравнением или рекуррентной формулой называется

соотношение

вида

an+ k = F(n, an , an+ 1 ,..., an+ k − 1 ) ,

которое

позволяет

вычислять

все

члены

последовательности a0 , a1 , a2 ,..., если заданы ее первые

k членов.

 

 

 

Пример 1.

 

 

 

1.

Формула an+ 1 =

an + d

задает арифметическую

прогрессию.

an+ 1 =

q × an

 

2.

Формула

определяет

геометрическую прогрессию.

 

 

3.

Формула

an + 2

= an + 1 + an

задает

последовательность чисел Фибоначчи.

В случае, когда рекуррентное соотношение линейно и однородно, т. е. выполняется соотношение вида

an+ k + p1an+ k − 1 + ... + pk an = 0

(1)

(p=const), последовательность a0 , a1 , a2 ,... называется

возвратной. Многочлен

154

 

P (x) = xk

+ p xk − 1 + ... +

p

k

 

a

1

 

 

 

(2)

 

 

 

 

называется

характеристическим

для

возвратной

последовательности {an }.

Корни

многочлена Pa (x)

называются характеристическими.

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

Описание общего уравнения соотношения (1) имеет аналоги с описанием решения обыкновенного дифференциального уравнения с постоянными коэффициентами.

Теорема

1.

1.

Пусть

 

λ

-

корень

характеристического

многочлена

 

(2).

Тогда

последовательность {n } ,

где

c –

произвольная

константа, удовлетворяет соотношению (1).

 

2.

Если

 

λ 1 ,λ 2 ,...,λ k

-

простые

корни

характеристического многочлена (2), то общее решение

рекуррентного

 

 

соотношения

(1)

имеет

вид

a

n

=

c λ n

+

c

2

λ n + ... +

c

k

λ n , где

c ,c

2

,...,c

k

-

 

 

1 1

 

 

2

 

k

1

 

 

произвольные константы.

 

 

 

ri (i = 1,..., s)

 

3.

Если

λ i

 

 

- корень

кратности

характеристического многочлена (2), то общее решение

рекуррентного

соотношения

(1)

имеет

вид

an = ås

(ci1 +

ci2 n + ... + cri nri− 1 )λ in ,

где cij

-

i= 1

 

 

 

 

 

произвольные константы.

155

Зная общее решение рекуррентного уравнения (1), по начальным условиям, a0 , a1 , a2 ,..., ak − 1 можно найти

неопределенные постоянные cij и те самым получить решение уравнения (1) с данными начальными условиями.

Пример

2. Найти последовательность {an },

удовлетворяющую

рекуррентному

соотношению

an+ 2 − 4an+ 1 +

3an = 0

и

начальным

условиям

a1 = 10, a2

= 16 .

 

 

Корням

 

характеристического

многочлена

P (x) = x2

4x + 3

являются числа

x1 = 1, x2 = 3.

a

 

 

 

 

Следовательно, по теореме 3.1. общее решение имеет вид

an = c1 + c2 3n . Используя

 

начальные условия,

получаем систему

 

 

 

 

ì c1

+

3c2

=

10,

í

+

9c2

=

16,

î c1

решая

которую,

находим c1 = 7

и

c2 = 1. Таким

образом,

an =

7 + 3n .

 

 

 

 

 

Рассмотрим

неоднородное

линейное

рекуррентное

уравнение

an+ k + p1an+ k− 1 +

...+

pk an =

f (n) =

0,1,...

 

 

(3)

Пусть {bn } - общее решение однородного уравнения (1), а {cn } - частное (конкретное) решение

156

неоднородного уравнения (3). Тогда последовательность {bn + cn } образует общее решение уравнения (3), и тем

самым справедлива.

Теорема 2. Общее решение неоднородного линейного рекуррентного уравнения представляется в виде суммы общего решения соответствующего однородного линейного рекуррентного уравнения и некоторого частного решения неоднородного уравнения.

Таким образом, в силу теоремы 1. задача нахождения общего решения рекуррентного уравнения (3) сводится к нахождению некоторого частного решения.

В отдельных случаях имеются общие рецепты нахождения общего решения.

Если

f (n) = β

n

(где

β )

не

является

характеристическим корнем, то, подставляя

an

= cβ n в

(3), получаем ck

+

 

p β

k − 1 + ... + p

k

) × β n

=

β n

и отсюда

 

 

 

 

 

1

 

 

 

 

 

 

c × Pa (b) = 1,

т.

е.

частное

решение

можно задать

формулой

an =

1

 

 

× β

n .

 

 

 

 

 

 

Pa (b)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Пусть

f (n) - многочлен степени r от переменной n, и

число 1 не является характеристическим корнем. Тогда и

частное решение следует искать в виде an = år di ni .

i= 0

157

Подставляя

многочлены

в

формулу

(3),

получаем

r

r

 

 

r

 

 

å di (n + k)i + p1 å (n + k − 1)i + ... +

pk å di ni

= =

i= 0

i= 0

 

 

i= 0

 

 

r

 

 

 

 

 

 

= å di ((n + k)i + p1 (n + k − 1)i + ... +

pk di ni ) =

 

i= 0

 

 

 

 

 

 

r

 

 

 

 

 

 

= å di (gi ni + ...) = f (n).

 

 

 

 

 

i= 0

 

 

 

 

 

 

Сравнивая

коэффициенты

в

левой и

правой частях

последнего равенства, получаем соотношения чисел di ,

позволяющие эти числа определить. Пример. Найти решение уравнения

an+ 1 + 2an = n + 1

(4)

с начальным условием a0 = 1.

Рассмотрим характеристический многочлен Pa (x) = x + 2 . Так как Pa (1)3 ¹ 0 и правая часть f (n) уравнения (3) равна n+1, то частное решение будем искать

в виде cn = d0 + d1n . Подставляя cn в уравнение (4), получаем

(d0 + d1 (n + 1)) + 2(d0 + d1 × n) = (3d0 + d1 ) + 3d1 × n = 1+ n

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

ì

3d0 +

d1

= 1,

í

3d1

=

1,

î

откуда находим d0 = 92 , d1 = 13 . Таким образом, частное

решение уравнения (4) имеет вид cn = 92 + 13 n . По теореме 3.1. общее решение однородного уравнения

158

an+ 1 + 2an =

0 задается формулой bn =

c × (- 2)n , и по

теореме

3.2.

получаем

общее решение

уравнения

(4):

an = 2 +

1 n +

c × (- 2)n .

Из

начального

условия

a0 = 1

9

3

 

 

c = 7 . Таким образом,

находим

2

+ c = 1, т.

е.

 

9

 

 

9

 

 

an = 2 +

1 n +

7 × (- 2)n .

 

 

 

 

9

3

9

 

 

 

 

Задача коммивояжера. Общее описание

Задача коммивояжера (в дальнейшем сокращённо - ЗК) является одной из знаменитых задач теории комбинаторики. Она была поставлена в 1934 году, и об неё, как об Великую теорему Ферма обламывали зубы лучшие математики. В своей области (оптимизации дискретных задач) ЗК служит своеобразным полигоном, на котором испытываются всё новые методы.

Постановка задачи следующая.

Коммивояжер (бродячий торговец) должен выйти из первого города, посетить по разу в неизвестном порядке города 2,1,3..n и вернуться в первый город. Расстояния между городами известны. В каком порядке следует обходить города, чтобы замкнутый путь (тур) коммивояжера был кратчайшим?

Чтобы привести задачу к научному виду, введём некоторые термины. Итак, города перенумерованы числами jÎТ=(1,2,3..n). Тур коммивояжера может быть описан циклической перестановкой t=(j1,j2,..,jn,j1), причём все j1..jn – разные номера; повторяющийся в начале и в конце j1, показывает, что перестановка зациклена. Расстояния между парами вершин Сij образуют матрицу С. Задача состоит в том, чтобы найти такой тур t, чтобы минимизировать функционал

Относительно математизированной формулировки ЗК

159

уместно сделать два замечания.

Во-первых, в постановке Сij означали расстояния, поэтому они должны быть неотрицательными, т.е. для всех jÎТ:

Сij³0; Cjj=∞

(2)

(последнее равенство означает запрет на петли в туре), симметричными, т.е. для всех i,j:

Сij= Сji.

(3

 

)

и удовлетворять неравенству треугольника, т.е. для

всех:

(4

Сij+ Сjk³Cik

 

)

В терминах теории графов симметричную ЗК можно

сформулировать так:

 

Дана полная сеть с n

вершинами, длина ребра (i,j)= Сij.

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

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

Методы решения ЗК Жадный алгоритм

Жадный алгоритм – алгоритм нахождения наикратчайшего расстояния путём выбора самого

короткого, ещё не выбранного ребра, при условии, что оно не образует цикла с уже выбранными рёбрами. «Жадным» этот алгоритм назван потому, что на последних шагах приходится жестоко расплачиваться за жадность.

Посмотрим, как поведет себя при решении ЗК жадный алгоритм. Здесь он превратится в стратегию «иди в

160

ближайший (в который еще не входил) город». Жадный алгоритм, очевидно, бессилен в этой задаче. Рассмотрим для примера сеть на рис. 2, представляющую узкий ромб. Пусть коммивояжер стартует из города 1. Алгоритм «иди вы ближайший город» выведет его в город 2, затем 3, затем 4; на последнем шаге придется платить за жадность, возвращаясь по длинной диагонали ромба. В результате получится не кратчайший, а длиннейший тур.

В пользу процедуры «иди в ближайший» можно сказать лишь то, что при старте из одного города она не уступит стратегии «иди в дальнейший».

Как видим, жадный алгоритм ошибается. Можно ли доказать, что он ошибается умеренно, что полученный им тур хуже минимального, положим, в 1000 раз? Мы докажем, что этого доказать нельзя, причем не только для жадного логарифма, а для алгоритмов гораздо более мощных. Но сначала нужно договориться, как оценивать погрешность неточных алгоритмов, для определенности, в задаче минимизации. Пусть fB - настоящий минимум, а fA - тот квазиминимум, который получен по алгоритму. Ясно, что fA/ fB≥1, но это – тривиальное утверждение, что может быть погрешность. Чтобы оценить её, нужно зажать отношение оценкой сверху:

fA/fB ≥1+ nε,

где, как обычно в высшей математике, ε≥0, но, против обычая, может быть очень большим. Величина ε и будет служить мерой погрешности. Если алгоритм минимизации будет удовлетворять неравенству (5), мы будем говорить, что он имеет погрешность ε.

Деревянный алгоритм.

Теперь можно обсудить алгоритм решения ЗК через построение кратчайшего остовного дерева. Для краткости будет называть этот алгоритм деревянным.

Построим на входной сети ЗК кратчайшее остовное

161

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

Построим эйлеров цикл G, начиная с вершины 1, цикл задается перечнем вершин.

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

Пример 1. Дана полная сеть, показанная на рис.5. Найти тур жадным и деревянным алгоритмами.

 

 

1

 

2

3

4

5

6

-

 

 

1

 

-

 

6

4

8

7

1

 

 

4

2

 

6

 

-

7

1

7

1

 

 

1

0

3

 

4

 

7

-

4

3

1

 

 

0

4

 

8

 

1

4

-

5

1

 

1

 

1

5

 

7

 

7

3

5

-

7

 

 

1

 

1

1

1

7

-

 

4

 

0

 

0

1

табл. 1

 

 

 

 

 

 

Решение. Жадный алгоритм (иди в ближайший город из города 1) дает тур 1–(4)–3-(3)–5(5)–4–(11)–6–(10)–2–

(6)–1, где без скобок показаны номера вершин, а в скобках

162

– длины ребер. Длина тура равна 39, тур показана на рис. 5.

2. Деревянный алгоритм вначале строит остовное дерево, показанное на рис. 6 штриховой линией, затем

эйлеров цикл 1-2-1-3-4-3-5-6-5-3-1, затем тур 1-2-3-4-5-6-1 длиной 43, который показан сплошной линией на рис. 6.

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

приблизительными, а не просто эвристическими. Известно еще несколько простых алгоритмов,

гарантирующих в худшем случае ε=1. Для того, чтобы найти среди них алгоритм поточнее, зайдем с другого конца и для начала опишем «brute-force enumeration» - «перебор животной силой», как его называют в англоязычной литературе. Понятно, что полный перебор практически применим только в задачах малого размера. Напомним, что ЗК с n городами требует при полном переборе рассмотрения (n-1)!/2 туров в симметричной задаче и (n-1)! Туров в несимметричной, а факториал, как показано в следующей таблице, растет удручающе быстро:

5!

10!

15!

20!

25!

30!

35!

40!

45!

50!

~10

~10

~10

~10

~101

~10

~10

~10

~10

~106

2

6

12

18

25

32

40

47

56

4

 

Чтобы

проводить

полный

перебор в

ЗК,

нужно

научиться (разумеется, без повторений) генерировать все перестановки заданного числа m элементов. Это можно

163

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

Пусть имеется некоторый алфавит и наборы символов алфавита (букв), называемые словами. Буквы в алфавите упорядочены: например, в русском алфавите порядок букв а б я (символ читается «предшествует)». Если задан порядок букв, можно упорядочить и слова. Скажем, дано слово u=(u1,u2,..,um) – состоящее из букв u1,u2,..,um - и слово v =(v1,v2,..,vb). Тогда если u1 v1, то и u v, если же u1=v1, то сравнивают вторые буквы и т.д. Этот порядок слов и называется лексикографическим. Поэтому в русских словарях (лексиконах) слово «абажур» стоит раньше слова «абака». Слово «бур» стоит раньше слова «бура», потому что пробел считается предшествующим любой букве алфавита.

Рассмотрим, скажем, перестановки из пяти элементов, обозначенных цифрами 1..5. Лексикографически первой перестановкой является 1-2-3-4-5, второй – 1-2-3-5-4, …, последней – 5-4-3-2-1. Нужно осознать общий алгоритм преобразования любой перестановки в непосредственно следующую.

Правило такое: скажем, дана перестановка 1-3-5-4-2. Нужно двигаться по перестановке справа налево, пока впервые не увидим число, меньшее, чем предыдущее (в примере это 3 после 5). Это число, Pi-1 надо увеличить, поставив вместо него какое-то число из расположенных правее, от Pi до Pn. Число большее, чем Pi-1, несомненно, найдется, так как Pi-1< Pi . Если есть несколько больших чисел, то, очевидно, надо ставить меньшее из них. Пусть это будет Pj,j>i-1. Затем число Pi-1 и все числа от Pi до Pn, не считая Pj нужно упорядочить по возрастанию. В результате получится непосредственно следующая

164

перестановка, в примере – 1-4-2-3-5. Потом получится 1- 4-2-5-3 (тот же алгоритм, но упрощенный случай) и т.д.

Нужно понимать, что в ЗК с n городами не нужны все перестановки из n элементов. Потому что перестановки, скажем, 1-3-5-4-2 и 3-5-4-2-1 (последний элемент соединен с первым) задают один и тот же тур, считанный сперва с города 1, а потом с города 3. Поэтому нужно зафиксировать начальный город 1 и присоединять к нему все перестановки из остальных элементов. Этот перебор даст (n-1)! разных туров, т.е. полный перебор в несимметричной ЗК (мы по-прежнему будем различать туры 1-3-5-4-2 и 1-2-4-5-3).

Пример 2. Решим ЗК, поставленную в Примере 1 лексикографическим перебором. Приведенная выше программа напечатает города, составляющие лучший тур: 1-2-6-5-4-3 и его длину 36.

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

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

165

166

46. Алгоритмические задачи поиска в графах: задачи Прима-Краскала, Дейкстры, Форда-Фалкерсона.

Классификация алгоритмических задач на графах

Задача сетевого планирования:

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

А) Найти длиннейший путь (без повторения) от входа к выходу вдоль направления стрелок. Путь считается больше, если сумма длин его дуг больше; В) Определение длиннейшего или кратчайшего пути от входа к вершинам по направлению; С) Определение тупиков и контуров в сети.

Тупик - висячая вершина, у которой есть входящий поток и нет выходящего.

Контур – простой цикл, построенный по направлению. Задача поиска: алгоритмы поиска тупиков являются алгоритмами поиска всех вершин с определением степени входа и выхода для всех вершин Эти значения не могут быть = 0Þ найдя нулевую степень мы найдем вершину, являющуюся тупиком.

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

Задача о максимальном потоке Сеть – связный граф, часть вершин которого выделена и

наз-ся полюсами. Различают однополюсные и двухполюсные сети.

Транспортной сетью наз-ют двухполюсную сеть, в одном – исток, в другом – сток, они имеют направление и длину (пропускная способность сети).

167

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

Для потоков должны выполняться законы Кирхгофа:

в любой вершине сумма входящих потоков = сумме выходящих

входной поток всей сети = выходному потоку данной

сети Сечением сети – наз-ся такое множество ребер, которые

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

В задачах max и min пропускной способности сети требуется определить в соответствии с теоремой ФордаФолкерсона, min пропускную способность простого сечения.

Простое сечение – сечение. У которого нет ребер, которые можно исключить.

Задача о максимальном потоке или задача ФордаФалкерсона

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

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

Задача – наладить максимальный поток из источников в стоки.

Теорема Форда-Фолкерсона

168

вх.вых

Max поток через сеть = min потоку через простое сечение. Док-во: (методом моделирования).

Max поток через сеть существует и конечен, т.к. пропускная способность и кол-во дуг – конечные величины. Дуга наз-ся насыщенной, если max = пропускной способности.

Если бы все дуги были насыщены. То в сети был бы максимально возможный поток, но в реальности должны выполняться законы Кирхгофа, Þ дуги не будут насыщены. Пусть в сети будет установлен максимальный поток. Проанализируем ситуацию, когда сеть разделена различными простыми сечениями. Т.к. простые сечения делят на две части, то входящий поток в сечение = max потоку. Расставим эти сечения по пропускной способности, в порядке убывания, Þ , найдем сечение с min пропускной способностью. Докажем, что это сечение будет иметь только насыщенные ребра. Пусть одно ребро из min сечения не насыщенно, тогда возможность увеличить поток через данное сечение, сделав это ребро насыщенным. Т.о. min пропускная способность данного сечения позволит наращивать поток через него до тех пор, пока все ребра не будут насыщенными. Дальнейшее увеличение потока невозможно. Þ Ч.Т.Д.

Алгоритм получения максимального потока

Всоответствии с теоремой существует 2 варианта:

1.Найти все простые сечения и найти между них наименьшее.

2.Строится какой-либо поток через сеть. Двигаясь от выхода, стараемся увеличить данный поток путем перераспределения по ребрам. Как только получается

169

простое сечение, у которого ребра насыщенны Þ найдем простое сечение.

Задача Прима-Краскала

Эта задача определения остовного дерева в полном графе с заданными длинами ребер такое, что это остовное дерево имеет min длину.

Втерминах теории графов задача Прима-Краскала выглядит следующим образом:

Дан полный граф с n вершинами, длины ребер заданы. Найти остовное дерево минимальной длины.

Втаком виде задача была поставлена и решена Примом в 1961 г.

Краскал одновременно и независимо поставил и решил задачу не для плоского случая, где расстояния определяются по формуле (1), а для произвольных положитедьных dij, I,j = 1,.., n. При этом для некоторых пар индексов dij бесконечно, что означает отсутствие ребра, т.е. рассматривает любой граф, а не только полный. Есть n городов, кот-ые нужно соединить телефонной сетью с min затратами. Затраты определяются длиной кабеля. Известно расстояние между городами. Требуется построить телефонную линию так, чтобы не было дублирования и длина была минимальной.

Для решения данной задачи существует 1 алгоритма: алгоритм Прима и алгоритм Краскала.

Алгоритм Прима.

1.Строятся все вершины для графа без ребер.

2.Выбирается самое короткое ребро

3.Теперь имеем некоторое дерево, к которому нужно добавлять вершины и ребра, пока не будут связаны все вершины.

4.Добавляется только висячая вершина с ребром.

Врезультате добавления алгоритм строится по следующим шагам:

170

Рассматриваем все кол-во ребер, кот. не связаны с построенным деревом.

Определяем длины ребер, которыми эти вершины могут быть присоединены. Оставляем у каждой вершины кратное ей ребро.

Выбираем ребро. У которого длина кратчайшая и соединяем его с деревом. В результате дерево увеличится на одно ребро.

Первые три пункта повторяются, пока не останется

изолированных вершин.

Алгоритм Краскала

Алгоритм Краскала противоположен алгоритму Прима. Здесь удаляются длиннейшие ребра по следующему правилу:

1.Определяем в графе циклические ребра.

2.Определяется наибольшее циклическое ребро и удаляется.

3.Повторяем первые 2 пункта до полного исчезновения циклических ребер.

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

Теорема Прима-Краскала

Оба алгоритма дают одно и то же дерево, которое имеет min длину.

Док-во.

1.Алгоритмы Прима-Краскала удаляют только циклические ребра или добавляют антициклические Þ

171

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

2.Докажем, что алгоритмы П-К дают одинаковое дерево. Используем метод от противного.

Пусть Краскал дал дерево Гк, а Прим – Гп., кот. не равны. Сравним эти деревья и возьмем произвольную вершину А. По алгоритму Прима она соединена с остальными вершинами только одним ребром, кот. имеет min длину. А- последняя вершина алгоритма Прима. Найдем эту вершину в дереве Краскала. Если эта вершина соединена с остальными вершинами другим ребром, то образуется цикл, в кот. по алгоритму Краскала, мы должны удалить длиннейшее реброÞ получено противоречие. Поскольку удалено не длиннейшее ребро Þ предположение о неравенстве деревьев ошибочно. Деревья одинаковы.

Задача Дейкстры

Задача Дейкстры – это задача поиска кратчайшего пути между вершинами графа с заданными длинами ребер. Обычно находятся кратчайшие пути между всеми вершинами.

Алгоритм Дейкстры

Пусть задан граф из n вершин и длина ребер.

1.Строим таблицу, где столбцы будут относиться к вершинам. Но на одном шаге таблица пуста.

2.Выбираем вершину, кот. будет основной на данном шаге из условия такой близости к исходной (вначале это вершина А).

172

3.Проставим расстояния от выделенной вершины до остальных (если вершины не соединены, то ставится «-», знак или Б).

4.Прекращаем заполнение столбца, у кот. была выделена вершина.

5.Среди оставшихся столбцов находим наименьшее значение. Вершина данного столбца будет выделена.

6.Повторяем шаг 2-5, но с условием: цифру, кот. мы записываем в расстояние от данной вершины, надо выбирать наименьшую из 2-х выше лежащей цифры или сумму цифр выбранной вершины + расстояние от выбранной вершины.

7.Построение таблицы завершается, когда выделена последняя вершина, расстояние которой не уменьшается.

Теорема Дейкстры

Алгоритм Дейкстры корректен, дает правильный результат для любого графа.

В качестве док-ва можно рассмотреть простые соображения – методом от противного.

Если бы из А в X существовал более короткий путь, то он обязательно отражался бы в одной из строчек столбца X0, т.к. путь в X рассматривается из всех вершин. Т.о., наличие непроверенного короткого пути в X требует наличие таких же непроверенных путей для всех вершин этого пути, что в принципе невозможно Þ Ч.Т.Д.

Существует удобный алгоритм Флойда-Уоршела Для решения задачи Дейкстры.

 

ì

 

 

dij

 

ü

 

dij =

ï

 

 

ï

dij - матрица кратчайших

miní

 

 

 

 

ý , где

d

 

+ d

 

 

ï

ik

ï

 

 

î

 

 

kj þ

 

путей между вершинами X j

и X i .

173

Вычисление по этой формуле в цикле по i , по j и внутри цикла k.

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

Алгоритм Уоршелла

удобный алгоритм Флойда-Уоршелла для решения задачи Дейкстры

 

ì

dij

 

ü

dij =

ï

ï

miní

 

 

ý , где

dik +

 

 

ï

dkj ï

 

î

 

 

þ

dij - матрица кратчайших расстояний между вершинами X j и X i . Вычисление по этой формуле в цикле по i , по j и внутри цикла k .

174

47 Рекурсивные функции

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

Как известно, величину w называют функцией, а величины x1,x2,…,xn

аргументами, или независимыми переменными, если известен закон, который для различных наборов конкретных значений величин x1,x2,…,xn задает определенные значения величины w. При этом для каждого набора допускается одно-единственное значение функции. В частном случае функция может иметь одно независимое переменное (аргумент). Что за закон применяется для определения функции? Математика не накладывает никаких ограничений на него. Она допускает любой мыслимый закон. Но таким законом может быть некоторый алгоритм. В этом случае функцию называют вычислимой, так как имеется способ получения ее значений. Рекурсивными функциями называют один частный класс вычислимых функций. Алгоритмы, являющиеся законами их задания, мы будем называть

алгоритмами, сопутствующими рекурсивным функциям.

По Черчу числовая функция называется рекурсивной, если она относится к одному из двух классов:

1.Базовым рекурсивным функциям (алгоритм получения таких функций считается очевидным)

175

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

суперпозиции, примитивной рекурсии и минимизации. Замечание. В первой редакции данного определения оператор минимизации отсутствует.

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

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

Базовые функции Базовые функции бывают трех типов: 1. Функции любого числа независимых переменных,

тождественно равные нулю. Для краткости будем называть их «тождественный ноль» Их будем обозначать φn, где п — число аргументов. Например, к числу таких функций относятся у= φ1(x), w=φ3(x, у, z), w=φn(x1,x2,…,xn). Сопутствующий алгоритм для этих функций гласит: «Если функциональный знак имеет вид φn, то любой совокупности значений аргументов данной функции ставится в соответствие ее значение 0».

Например, f(x)=x-x, может быть обозначение: φ(x)=x-x≡0. Будем считать, что п может быть равно нулю, т. е. что возможна функция этого вида, не зависящая ни от одного

176

аргумента. Эта функция равна 0. Обозначим ее φ0(), или, для краткости, φ0.

2. Функции любого числа независимых переменных,

тождественно равные одному из аргументов. Обозначим их ψn,i где п — число аргументов, i — номер одного из аргументов 1<i<n). Сопутствующий этим функциям алгоритм гласит: «Если функциональный знак имеет вид ψn,i, то значением функций считать значение i-го (считая в функциональной записи слева направо) независимого переменного».

Например: ψ1,3(x,y,z)=x.

Для тождественных функций ни n, ни i не может быть равно нулю.

3. Функции следования (иначе — получения последователя) одного независимого переменного. Обозначим их с помощью функционального знака λ(х). Сопутствующий этим функциям алгоритм гласит: «Если функциональный знак имеет вид λ(х), то значением функции считать число, непосредственно следующее за числом, являющимся значением аргумента». Операция «получения последователя», по-видимому, проще сложения. Дети сначала учатся считать, а потом уже овладевают сложением. Первобытные люди тоже сначала овладели счетом, и лишь много позже возникла идея сложения чисел. Это вполне естественно, так как в ту пору числа изображали как последовательности черточек (зарубок). Последователь получали, добавляя еще одну зарубку.

Например: λ(х)=x+1; λ(3)=3+1=4.

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

177

до тех пор, пока мы не построим класс рекурсивных функций).

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

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

В теории рекурсивных функции особое значение имеют три следующих оператора: Оператор суперпозиции, оператор примитивной рекурсии и оператор минимизации.

Оператор суперпозиции или подстановки.Слова

суперпозиция и подстановка в данном случае имеют одно и то же значение. Этот оператор по функции F от п аргументов и по функциям f1,f2,…,fn строит новую функцию Ф такую, что для нее справедливо тождество Ф≡F(f1,f2,…,fn).

Алгоритм, сопутствующий этому оператору, гласит: «Значения функций f1,f2,…,fn принять за значения аргументов функции F и вычислить ее значение». Оператор подстановки (суперпозиции) обозначим буквой С. Построение функции Ф из функций F и fi с помощью оператора суперпозиции будем записывать так: Ф=С(F,f1,f2,…,fn).

Алгоритм построения суперпозиции (для двух функций). 1. Выбираются две функции f, g.

178

2.Определяется аргумент xk первой функции f, для которой будем осуществлять подстановку.

3.Подставляем значение аргумента в g и вычисляем её значение go.

4.xk=go.

5.fo=f(x1,x2,…,xn)

Например, если в качестве F принять λ(х), а в качестве f1 взять функцию λ(у), то с помощью операции суперпозиции получим функцию τ(у) = λ(λ(у)).

Правило суперпозиции Суперпозиция двух рекурсивных функций является рекурсивной функцией.

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

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

Пример: F(x,y)=x+y и даны две функции g(x), f(x). Построим суперпозицию: Ф=C(F,g(x),f(y))=g(x)+f(y).

Оператор примитивной рекурсии. Этот оператор по двум функциям, одна из которых имеет п-1 независимых переменных, а другая, кроме указанных независимых переменных, имеет еще два (т. е. зависит от п+1 переменных), строит функцию n независимых переменных. Один из дополнительных аргументов войдет вместе с аргументами первой функции в число аргументов вновь получаемой функции, а другой играет вспомогательную роль при выполнении оператора рекурсии. Оператор рекурсии будем обозначать Пр; его применение будем записывать в виде строки: f= Пр(φ,ψ), где f означает получаемую функцию, φ — функцию п—1

179

независимых переменных, ψ — функцию п+1 независимых переменных.

При описании существа оператора рекурсии удобно не указывать аргументов первой из заданных функций ни в ее функциональной записи, ни в записях двух других функций, подразумевая эти аргументы. Тогда можно сказать, что оператор рекурсии задает функцию с помощью двух условий, в которые входят функции φ и ψ. Алгоритм, сопутствующий оператору рекурсии, гласит: «Значением получаемой функции для нулевого значения главного дополнительного аргумента считать значение исходной функции п -1 аргументов; значением определяемой функции для каждого последующего значения главного аргумента считать значение второй из заданных функций при предыдущем значении главного аргумента и при значении вспомогательного аргумента, совпадающем с предыдущим значением определяемой функции».

Оператор примитивной рекурсии строится по следующему правилу:

1. f(x1,x2,…,xn-1 ,0) = φ(х12,…,xn-1).

2. f(x1,x2,…,xn-1 ,y+1)= ψ(x1,x2,…,xn-1 ,y,f( x1,x2,…,xn-1, y )).

При этом, f(x1,x2,…,xn-1 ,y+1)=C(ψ(x1,x2,…,y,xn+1),f( x1,x2,…,xn- 1, y)).

Алгоритм построения примитивной рекурсии:

1.Выбираем две функции φ и ψ, у которых количество аргументов п-1 и п+1 соответственно;

2.Определяем значение для п-1 аргумента и фиксируем значение хп (п-го аргумента), это будет у;

3.Выбираем значение у=0;

4.Вычисляем f(x1,x2,…,xn-1 ,0) = φ(х12,…,xn-1);

5.Увеличиваем у на 1 и получаем функцию

ψ(x1,x2,…,xn-1 ,y,f( x1,x2,…,xn-1, y ))= f(x1,x2,…,xn-1 ,y+1).

180

Правило примитивной рекурсии Если заданы две рекурсивные функции (φ от п-1 аргумена и ψ от п+1 аргумента, то построенная с их помощью примитивная рекурсия даст тоже рекурсивную функцию.

Примеры: I. Доказать рекурсивность функции f(x,y)=x+y. 1. f(x,0)=x – рекурсивна, как базовая.

2. f(x,y+1)=x+(y+1)=x+y+1=z+1 – базовая, как функция следования.

z+1=ψ(x,y,z)= ψ(x,y,f(x,y))=(x+y)+1=x+(y+1)=f(x,y+1).

II. Доказать рекурсивность функции f(x,y)=xy.

1.f(x,0)=x0=1=λ(0) – рекурсивна, как базовая.

2.f(x,y+1)=xy+1=xy٠x=z٠x – рекурсивная.

ψ(x,y,z)=x٠z; ψ(x,y, f(x,y))=z٠x= xy٠x= xy+1= f(x,y+1).

Оператор построения по первому нулю

Этот оператор называют обычно оператором наименьшего числа, а в некоторых книгах — оператором минимизации; Этот оператор по заданной функции, зависящей от n+1 аргументов, строит новую функцию от n аргументов. Исчезающий аргумент является вспомогательным и используется при выполнении оператора. Обозначают оператор построения по первому нулю буквой μ, его применение обозначают строкой вида f::= μ[f1;(x)], где x — исчезающий аргумент. С помощью оператора построения по первому нулю получают функцию f, значения которой определяются при выполнении сопутствующего ей алгоритма, который гласит: «Придавать вспомогательному аргументу последовательные значения, начиная с 0, до тех пор, пока не окажется, что функция f стала (в первый раз) равной нулю. Полученное значение вспомогательного аргумента принять за значение определяемой функции, соответствующее тем значениям основных аргументов, при которых осуществлялся описанный процесс».

181

Другими словами, пусть дана функция f(x1,x2,…,xn). Выберем одну из переменных хк и назовем её у. Получим

f(x1,x2,…,xk-1,y,xk+1…,xn)=f(x,y).

Пусть задано уравнение f(x,y)= 0. Найдем корень этого уравнения относительно у при фиксированном значении х. Возможны три ситуации:

1.Нет ни одного корня для натурального значения у,

2.Существует один корень при натуральному;

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

1.выбираем y=0;

2.проверяем равны ли нулю значения функции f при заданном у. Если равны, то у - первый корень и выходим из алгоритма. Если у≠0, то переходим к следующему пункту;

3.увеличиваем у на единицу, у=у+1;

4.возвращаемся к пункту 2).

Если функция имеет конечный корень среди натуральных чисел, то алгоритм обязательно даст результат. Если корней несколько, то обязательно будет найден самый меньший среди натуральных корней. Пользуясь данным алгоритмом поиска корня, можно построить функцию g(x1,x2,…,xk-1,xk+1…,xn). Запишем алгоритм построения функции g.

1)фиксируем значение переменных x1,x2,…,xn;

2)строим некую функцию f, к которой будет добавлена переменная хк;

3)определяем, имеет ли относительно этой переменной функция/натуральный корень. Если корней нет, то при данных значениях функция g не определена. Если корни

182

есть, то находим минимальный корень у. Этот корень и есть искомое значение функции g, g=y.

Подобный алгоритм определяет некоторую функцию, которая при одних значениях аргумента определена, а при других значениях не определена.

Функция, полученная по приведенному выше алгоритму, обозначается

g(x1,x2,…,xk-1,xk+1…,xn)= μ[f(x1,x2,…,xk-1,xk+1…,xn);y]. Построим μ[f(x,y);y] для f(x,y) = x-y+1. Очевидно, что

данная функция равна нулю при

у = х-1, следовательно g(x) = х-1, при этом функция g не определена при х=0. То есть, μ[f(x,y) = х-у+1, у]=х-1. Заметим, что базовые функции и функции, получаемые при помощи операторов подстановки и рекурсии, но без применения оператора построения по первому нулю, определены (имеют значения) для любых значений аргументов. Иначе обстоит дело с функциями, полученными при помощи оператора построения по первому нулю. Для некоторых комбинаций значений аргументов (даже для очень многих) они могут быть не определены, потому что исходная функция не принимает нулевых значений.

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

ψ2,1(x,y).

f=μ[ψ2,1(x,y),(x)]. Оператор для данной функции определен только в одной (.)x=0: ψ2,1(0,y)=0.

f=μ[ψ2,1(x,y),(y)], здесь ψ2,1(x,0)=x.

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

183

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

Сформулируем правило минимизации.

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

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

Изучая рекурсивные и частично рекурсивные функции, можно сформулировать ещё один тезис.

Тезис Черча: Любая всюду определенная вычислимая числовая функция является общерекурсивной. И, наоборот, если всюду определенная числовая функция не является общерекурсивной, то она невычислима.

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

Основной тезис.

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

Тезис Клини: Любая вычислимая, но не всюду определенная числовая функция является частично рекурсивной. Если частично определенная числовая

184

функция не является частично рекурсивной, то она невычислима.

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

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

185

48. Виртуальные машины Тьюринга. Нормальные алгорифмы Маркова.

Английский математик А. Тьюринг в 1937 г. опубликовал работу, в которой уточнял понятие алгоритма, прибегая к воображаемой вычислительной машине, известной теперь как машина Тьюринга. Основная идея машины Тьюринга и Поста заключалась в том, что алгоритмические процессы - это процедура, которые может совершать подходящее устройство «машина». На таких машинах оказалось возможным имитировать все алгоритмические процессы.

Абстрактным алфавитом (или просто алфавитом) конечное непустое множество символов, называемых буквами алфавита. Словами (или строками) в некотором алфавите А будем называть конечные последовательности букв этого алфавита. Длина слово-количество букв в нем. Слово нулевой длины называем пустым и обозначим «_» алфавит обозначим А, В, С….

Под машиной Тьюринга и Поста понимается некая гипотетическая (условная) машина, состоящая из следующих частей: 1. информационной ленты, представляемую собой бесконечную память машины. Лента разделена на ячейки, в котором можно записать один символ. Конечная совокупность символов алфавита, с которой работает машина, называется внутренним алфавитом. 2. «Головки чтения записи» - специального устройство, способного «считывать» символ ячейки. Головка представляется вдоль ленты вправо и влево так, что в каждый момент времени способна «видеть» только 1 ячейку. 3. Управляющее устройство, кот в каждый момент времени может находится в некотором состоянии, количество состояний, конечно. Состояние устройства управления называют внутренним состоянием машины. Одно из внутренних состояний называется заключительным состоянием. Переход к этому состоянию

187

сигнализирует о конце работы. Совокупность состояний устройства управления называется внешним алфавитом. Цель работы МТ - в зависимости от слова, записанного на ленте(входное слово) переписать его так, чтобы на ленте было другое слово-результат.

Описание МТ. Пусть заданы внешний А={ a1,a2...an ,.. } и

внутренний алфавит P={ P1, P2...Pn ,.. }. Лента бесконечна по

обе стороны разбита на клетки. Запись символа в ячейку МТ приводит к замене ее содержимого. Головка чтениязаписи может сдвигаться на одну вправо или влево или остаться неподвижной. Основной частью МТ является логический блок. Он имеет 2 входных канала: по одному

из них поступает ai знак из ячейки, по другому знак Pi того

состояния, кот приписывается логическому блоку на данный такт. По выходному каналу логический блок

посылает в текущую ячейку соот-щий знак ai ,

являющийся однознач-й функцией от сигналов ( ai , Pi )

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

1.Заставляет головку прочитать букву, кот-я стоит на ленте под ней.

2.В зависимости от прочит-й буквы и того состояния, в кот-м находится он сам,

а) заставляет головку записывать на ленте в той клетке, кот-я наход-ся под ней, некот-ю букву.

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

3. Если в результате действий, в п.2, буква, располож-ная под головкой, положение головки и сост-ние лог. блока

188

окажутся теми же, кот. были непосред-но перед выполнением этих действий, машина останавл-ся. В осталных случаях возвращается в п.1. Введем обозначения

d0,d+ , dдля состоя-ия ленты(на месте влево вправо). Если головка читает букву ai и блок наход-ся в состоя-ии

Pi , тот поведение машины определяет запись ax Pydz

означающую: «записать

на ленте

вместо ai букву

ax ,

совершить

перемещение

ленты dz , логическому

блоку

перейти в

состояние Py

». Таким

образом результатом

может быть 3 ситуации: 1. Машина выполнила несколько шагов и остановилась, слово при этом не изменилось. 2. Машина выполнила несколько шагов, слово изменилось. 3. Машина никогда не остановиться, приводя к бесконечному изменению состояний. Остановка МТ осущест-ся в 3-х случаях: 1. внутрен-е состояние управляющего устройства не изменяется.

2.управляющее устройство остается на месте.

3.буква в противолеж-ей ячейке не изменяется. Программа МТ. Совокупность команд, кот-е должна

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

P0 . Будем считать МТ заданной если заданы ее внут-й и

внеш-й алгоритмы. Представим работу МТ на примере.

Программа прибавления 1 к десятичному числу для машины Тьюринга

189

Пошаговое решение задачи

1._18_-P0

2._ 18_-P1

3._18 _-P1

4._18_-P1

5._18_-P2

6._19_-P3

7._19_-P3- остановка

Остановка машины произойдет тогда, когда мы прибавим к числу 1, то есть вернемся к началу слова. Очев-о, что машина останавливается, если в состоянии P2 встречает цифры от 0 до 8 и когда встречает символ ‘_’, заменяя его при этом на 1.

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

190

Если для функции f (x) имеется машина, реализующая ее, то говорят, что f (x) вычислима по Тьюрингу. Функцию,

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

Машина Поста. Как и МТ относится к классу абстрактных машин, создана практически в тоже время, что и МТ. МП состоит из бесконечной ленты, вдоль, кот в обоих направях перемещается каретка с головкой чтения-записи. Ячкйки ленты пронумерованы след-м образом (-3,-2,-1,0,1,2,3,)

-2 -1 0 1 2 В каждой ячейке ленты м.б. записан пустой символ «_» или символ-метка « I » На каждом шаге каретка перемещается только в одну сторону. Состояние МП определяется сост-ем ленты(комбинация пустых и занятых ячеек) и номером ячейки, на кот настроена каретка. Работа МП состоит в том, что каретка передвигается вдоль ленты и записывает или стирает

метки. Назовем командой одну зи 6-ти функций: 1. i = > j движение вправо. 2. i < = j движение влево. 3. i.vj запись . метки 4. ij стирание метки 5. i.?( j1, j2 ) передача

управления. 6. i. стоп –остановка все числа натуральные.

Пример. 137.= > j движ вправо 25.?(35,21) передача управления, 6386.стоп остановка.

Программа МП –конечный непустой список команд МП, обладающий след-ми св-ми: 1. Все команды послед-но пронумеров-ны, начиная с 1. 2. отсылка любой из команд (за исключением ком-ды стоп) есть номер одной команды прог-мы (включая номер той же команды).

Функционирование МП. Работа МП опред-ся согласно некот-й прог-ме и нача-му состо-ю. Будем считать, что в

191

нач-м сос-нии каретка всегда настроена на ячейку с номером 0, т.е нач-ое сос-ие опред-ся только содержимым ленты. Уточним команды 1. сдвиг каретки вправо на 1-у ячейку и переход на команду с номером 1. 2. сдвиг каретки влево на 1-у ячейку и переход на команду с номером j 3. записать метки в текущ-ю ячейку и переход на команду с

номером j (если в ячейке метка уже была, то команда не

выполнима). 4. стирание метки в текущей ячейке и переход на команду с номером j (если ячейка уже пуста, то команда не выполнима). 5. если обозреваемая ячейка пуста, переход

к команде с номером j1 в противном случае к j

2. 6. МП

останавливается. Выполнение команды может привести к 1-му из 3-х случаев: 1. Нормальная остановка по команде остановка. 2. аварийная ост-ка по невыполнимой команде.

3. зацикливание (бесконеч-я работа).

Тезис Поста. « числовая функция вычислима по Посту».

Гипотеза Поста.

Назовем числовым кортежем (или просто кортежем) упорядоченный набор чисел произвольной длины. Под длиной кортежа будем понимать количество чисел, входящих в него. Так кортеж {2, 2, 3, 6} имеет длину 6.

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

Задача (А). Получается из задачи (П) заменой слов «программа МП» на «алгоритм».

192

Гипотеза Поста: Задачи (А) и (П) одновременно либо имеют, либо не имеют решения.

Очевидно, что гипотеза Поста состоит из двух утверждений:

1)из разрешимости задачи (П) следует разрешимость задачи (А);

2)из разрешимости задачи (А) следует разрешимость задачи

(П).

Появление теории МТ и МП привело к следующим результатам:

1. Началось развитие более общей теории воображаемых

машин - теории автоматов

2.Была доказана алгоритмическая разрешимость большого класса задач в математике

3.Удалось доказать алгоритмическую неразрешимость некоторых задач в математике.

Нормальные алгорифмы Маркова

Советский ученый А. А. Марков избрал другой путь уточнения понятия алгоритма. Им разработана строгая теория класса алгоритмов, которые он назвал нормальными алгорифмами.

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

Если А и В – два алфавита, причем каждая буква алфавита А является буквой в В, а хотя бы одна из букв алфавита В не является буквой в Л, то 5 называется расширением алфавита А. Например, если А - {а, б, в, г), В={1, а, б, в, г, д}, то В являегся расширением А, так как содержит две буквы («1» и «д»), не являющиеся буквами в А, тогда как все

193

буквы алфавита А являются буквами в В.Рассмотрим какоелибо конкретное слово для определенности в алфавите русских букв, например слово «самолет». Мы видим, что из него можно вырезать подслова, например «сам», «амол» или «олет», или «лет», или, наконец, однобуквеиное слово «т». Про такие подслова говорят, что они входят в рассматриваемое слово или являются вхождениями в него. Заметим, что в наше слово входит и пустое слово, причем — несколько раз (оно входит перед первой буквой, между каждыми двумя буквами и, наконец, после последней буквы, т. е., в данном случае, 8 раз).

Подслово - часть слова, буквы которого расположены рядом. Подсловом может быть и само слово.

Условимся обозначать слова заглавными латинскими буквами (если эти буквы не являются буквами в применяемом алфавите). Если задано некоторое слово и нами выбрана буква, являющаяся его обозначением (именем), то будем ставить между ними знак = (равенства). Возвращаясь к нашему примеру, мы можем написать: для слова Я=самолет слово Р=амол является вхождением.

Заметим, что не только пустое слово может многократно входить в другое слово. Например, в слово Я=тарарам слово Р=ара входит два раза. Особый интерес для нас будет представлять так называемое первое вхождение.

Марковской подстановкой называется операция над словами, задаваемая с помощью пары слов (Р, Q), заключающаяся в следующем.

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

194

ни одного вхождения Р в R), то считается, что марковской подстановке слово R не поддается.

Частными случаями марковских подстановок являются (,Q), (Р,) и (,). В первом из приведенных примеров Р, во втором Q, а в третьем и Р, и Q являются пустыми.

Действие Марковской подстановки заключается в том, что в искомом слове ищется подслово слева направо, и как только находится, оно меняется на другое подслово. Если вхождений несколько, то при любой подстановке меняется только первое слева вхождение. Будем рассматривать слова в некотором алфавите А. Предположим, что символы « —» » и « . » не являются буквами в А. Запись Р-> Q и Р — . будем называть записями марковской подстановки (Р, Q), причем первую из них будем называть подстановкой, а вторую -

заключительной подстановкой.

Подстановки и заключительные подстановки будем называть формулами, различая в них левую часть Р и правую часть Q.

Марковская подстановка выполняется один раз, и если есть несколько вариантов, то выполняется подстановка, которая находится левее (ближе к началу слова). Марковская подстановка может быть успешной, неуспешной и конечной. Успешной - если подстановка выполнена, неуспешной, если подстановку выполнить нельзя и конечной, если в начале слова-замены стоит " . " Ее назначение - прекращение дальнейшего процесса Марковских подстановок.

Записью нормального алгоритма в алфавите А называют столбец формул, левые и правые части которых являются словами в А. Выполнение нормального алгоритма применительно к исходному данному R, являющемуся словом в А, заключается в следующем: 1. Двигаясь по столбцу формул, ищут первую формулу, левая часть ко торой входит в преобразуемое слово. 2.Если такой формулы не найдется, процесс окончен. 3. Если же она найдется, то

195

выполняют марковскую подстановку, соответствующую данной формуле, изменяя преобразуемое слово. 4. Затем смотрят, является ли выполненная подстановка заключительной. 5. Если она является заключительной, то процесс окончен. 6. В противном случае весь процесс повторяют с самого начала (то есть с пункта 1).

Этапы решения задач с помощью алгорифмов Маркова

Для составления алгорифма Маркова необходимо задать: 1. алфавит для записи слов и, возможно, расширенный алфавит для записи марковских преобразований (полученный путем добавления дополнительных технических букв); 2.определение

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

Порядок действия алгорифма Маркова:

1)записывается последовательность марковских подстановок и зада ется слово, на которое должен действовать этот алгорифм.

2)проверяется возможность марковской подстановки (1). Если она успешна, процесс повторяется, начиная с первой подстановки, если

неуспешна, то происходит переход к следующей подстановке. Если подстановка конечна, то прекращаем работу алгорифма.

3)если в результате использования алгоритма будет произведена ко нечная подстановка или ни одна из подстановок не будет успеш

ной, то алгорифм прекращает свою работу.

Результатом действия алгорифма Маркова может быть:

1) все подстановки неуспешны, мы получаем результат действия алгорифма.

196

2)в процессе работы выполнена конечная подстановка, результат работы есть.

3)алгорифм выполняется бесконечно.

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

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

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

197

49. Формальные языки и грамматики.

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

Далее цепочки символов будем обозначать греческими буквами: a, b, g.

Цепочка символов — это последовательность, в которую могут входить любые допустимые символы. Строка, которую вы сейчас читаете, является примером цепочки, допустимые символы в которой — строчные и заглавные русские буквы, знаки препинания и символ пробела. Но цепочка — это необязательно некоторая осмысленная последовательность символов. Последовательность “аввв..аагрьь ,..лл” — тоже пример цепочки символов. Цепочка символов — это упорядоченная последовательность символов. Это значит, что для цепочки символов имеют значение три фактора: состав входящих в цепочку символов, их количество, а также порядок символов в цепочке. Поэтому цепочки “а” и “аа”, а также “аб” и “ба” — это различные цепочки символов. Цепочки символов a и b равны (совпадают), a = b, если они имеют один и тот же состав символов, одно и то же их количество и одинаковый порядок следования символов в цепочке.

Количество символов в цепочке называют длиной цепочки. Длина цепочки символов a обозначается как |a|. Очевидно, что если a = b, то и |a| = |b|.

Основной операцией над цепочками символов является операция конкатенации (объединения или сложения) цепочек.

Конкатенация (сложение, объединение) двух цепочек символов — это дописывание второй цепочки в конец

199

первой. Конкатенация цепочек a и b обозначается как ab. Выполнить конкатенацию цепочек просто: например, если a = аб, а b = вг, то ab = абвг.

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

Алфавит — это счетное множество допустимых символов языка. Будем обозначать это множество символом V. Интересно, что согласно формальному определению, алфавит не обязательно должен быть конечным множеством, но реально все существующие языки строятся на основе конечных алфавитов.

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

Вобщем случае язык можно определить тремя способами: 1.перечислением всех допустимых цепочек языка; 2.указанием способа порождения цепочек языка (заданием грамматики языка); 3.определением метода распознавания цепочек языка.

Первый из методов является чисто формальным и на практике не применяется, так как большинство языков

200

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

Например, запись L({0,1}) = {0n1n, n > 0} задает язык над алфавитом V =

{0,1}, содержащий все последовательности с чередующимися символами 0 и 1, начинающиеся с 0 и заканчивающиеся 1. Видно, что пустая цепочка символов в этот язык не входит. Если изменить условие в этом определении с n > 0 на n і 0, то получим почти эквивалентный язык L'({0,1}), содержащий пустую цепочку.

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

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

201

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

Например, любой окончивший среднюю школу может сказать, что строка “3 + 2” является арифметическим выражением, а “3 2 +” — не является. Правда, не каждый задумается при этом, что он оперирует синтаксисом алгебры.

Семантика языка — это раздел языка, определяющий значение предложений языка. Семантика определяет “содержание языка” — задает смысл для всех допустимых цепочек языка. Семантика для большинства языков определяется неформальными методами (отношения между знаками и тем, что они обозначают, изучаются семиотикой). Чисто формальные языки лишены какоголибо смысла. Возвращаясь к примеру, приведенному выше, и используя семантику алгебры, мы можем сказать, что строка “3 + 2” есть сумма чисел 3 и 2, а также то, что “3 + 2 = 5” — это истинное выражение. Однако изложить любому ученику синтаксис алгебры гораздо проще, чем ее семантику, хотя в случае алгебры семантику как раз можно определить формально.

Лексика — это совокупность слов (словарный запас)

202

языка. Слово или лексическая единица (лексема) языка — это конструкция, которая состоит из элементов алфавита языка и не содержит в себе других конструкций. Иначе говоря, лексическая единица может содержать только элементарные символы и не может содержать других лексических единиц.

Лексическими единицами (лексемами) русского языка являются слова русского языка, а знаки препинания и пробелы представляют собой разделители, не образующие лексем. Лексическими единицами алгебры являются числа, знаки математических операций, обозначения функций и неизвестных величин. В языках программирования лексическими единицами являются ключевые слова, идентификаторы, константы, метки, знаки операций; в них также существуют и разделители (запятые, скобки, точки с запятой и т. д.).

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

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

203

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

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

Грамматика — это описание способа построения предложений некоторого языка. Иными словами, грамматика — это математическая система, определяющая язык.

Фактически, определив грамматику языка, мы указываем правила порождения цепочек символов, принадлежащих этому языку. Таким образом, грамматика — это генератор цепочек языка. Она относится ко второму способу определения языков — порождению цепочек символов. Грамматику языка можно описать различными способами. Например, грамматика русского языка описывается довольно сложным набором правил, которые изучают в начальной школе. Для некоторых языков (в том числе для синтаксических конструкций языков программирования) можно использовать формальное описание грамматики, построенное на основе системы правил (или продукций). Правило (или продукция) — это упорядоченная пара цепочек символов (a,b). В правилах важен порядок цепочек, поэтому их чаще записывают в виде a ® b (или

a ::= b). Такая запись читается как “a порождает b” или “b по определению есть a”.

Грамматика языка программирования содержит правила двух типов: первые (определяющие синтаксические конструкции языка) довольно легко поддаются формальному описанию; вторые (определяющие

204

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

Язык, заданный грамматикой G, обозначается как L(G). Две грамматики G и G' называются эквивалентными, если они определяют один и тот же язык: L(G) = L(G'). Две грамматики G и G' называются почти эквивалентными, если заданные ими языки различаются не более чем на пустую цепочку символов: L(G)И{1} = L(G')И{1}. Формально грамматика G определяется как четверка G(VT,VN,P,S), где:

VT — множество терминальных символов или алфавит терминальных символов;

VN — множество нетерминальных символов или алфавит нетерминальных символов;

P — множество правил (продукций) грамматики, вида a®b, где aО(VNИVT)+, bО(VNИVT)*;

S — целевой (начальный) символ грамматики SОVN.Во множестве правил грамматики может быть несколько правил, имеющих одинаковые левые части,

вида: a ® b1, a ® b2, … a ® bn. Тогда эти правила объединяют вместе и записывают в виде: a ® b1 | b2 |…| bn.

Одной строке в такой записи соответствует сразу n правил. Такую форму записи правил грамматики называют

формой Бэкуса—Наура. Форма Бэкуса—Наура предусматривает, как правило, также, что нетерминальные символы берутся в угловые скобки: < >. Иногда знак ® в правилах грамматики заменяют на знак ::= (что характерно для старых монографий), но это всего лишь незначительные модификации формы записи, не

205

влияющие на ее суть.

Ниже приведен пример грамматики, которая определяет язык целых десятичных чисел со знаком: G({0,1,2,3,4,5,6,7,8,9,–,+}, {<число>,<чс>,<цифра>},P,<число>)

P:

<<число> ® <чс> | +<чс> | –<чс> <<чс> ® <цифра> | <чс><цифра> <<цифра> ® 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

Рассмотрим составляющие элементы грамматики G:

множество терминальных символов VT содержит двенадцать элементов: десять десятичных цифр и два знака;

множество нетерминальных символов VN содержит три элемента: символы <число>, <чс> и <цифра>;

множество правил содержит 15 правил, которые записаны в три строки (то есть имеется только три различных правых части правил);

целевым символом грамматики является символ <число>.

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

Запись правил грамматик с использованием метасимволов Запись правил грамматик с

206

использованием метасимволов предполагает, что в строке правила грамматики могут встречаться специальные символы — метасимволы, — которые имеют особый смысл и трактуются специальным образом. В качестве таких метасимволов чаще всего используются следующие символы: ( ) (круглые скобки), [ ] (квадратные скобки), { } (фигурные скобки), " " (кавычки) и , (запятая). Эти метасимволы имеют следующий смысл:

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

квадратные скобки означают, что указанная в них цепочка может встречаться, а может и не встречаться в данном месте правила грамматики (то есть может быть в нем один раз или ни одного раза);

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

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

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

Вот как должны выглядеть правила рассмотренной выше грамматики G, если их записать с использованием метасимволов:

<число> ® [(+,–)]<цифра>{<цифра>} <цифра> ® 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

Вторая строка правил не нуждается в комментариях, а

207

первое правило читается так: “число есть цепочка символов, которая может начинаться с символов + или –, должна содержать дальше одну цифру, за которой может следовать любое количество цифр”. В отличие от формы Бэкуса—Наура, в форме записи с помощью метасимволов, как видно, во-первых, убран из грамматики малопонятный нетерминальный символ <чс>, а во-вторых — удалось полностью исключить рекурсию. Грамматика в итоге стала более понятной.

Форма записи правил с использованием метасимволов — это удобный и понятный способ представления правил грамматик. Она во многих случаях позволяет полностью избавиться от рекурсии, заменив ее символом итерации { } (фигурные скобки). Как будет понятно из дальнейшего материала, эта форма наиболее употребительна для одного из типов грамматик — регулярных грамматик.

Кроме указанных выше метасимволов в целях удобства записи в описаниях грамматик иногда используют и другие метасимволы, при этом предварительно дается разъяснение их смысла. Принцип записи от этого не меняется. Также иногда дополняют смысл уже существующих метасимволов. Например, для метасимвола { } (фигурные скобки) существует удобная форма записи, позволяющая ограничить число повторений цепочки символов, заключенной внутри них: { }n, где nОN и n > 0. Такая запись означает, что цепочка символов, стоящая в фигурных скобках, может быть повторена от 0 до n раз (не более n раз). Это очень удобный метод наложения ограничений на длину цепочки.

Для рассмотренной выше грамматики G таким способом можно, например, записать правила, если предположить, что она должна порождать целые десятичные числа, содержащие не более 15 цифр:

<<число> ® [(+,–)]<цифра>{<цифра>}14

208

<цифра> ® 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 Для записи того же самого ограничения в форме Бэкуса—

Наура или в форме с метасимволами потребовалось бы 15 правил.

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

В такой форме записи каждому нетерминальному символу грамматики соответствует диаграмма, построенная в виде направленного графа. Граф имеет следующие типы вершин:

точка входа (на диаграмме никак не обозначена, из нее просто начинается входная дуга графа);

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

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

узловая точка (на диаграмме обозначается жирной точкой или закрашенным кружком);

точка выхода (никак не обозначена, в нее просто входит выходная дуга графа).

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

209

направленными дугами графа (линиями со стрелками). Из входной точки дуги могут только выходить, а во входную точку — только входить. В остальные вершины дуги могут как входить, так и выходить (в правильно построенной грамматике каждая вершина должна иметь как минимум один вход и как минимум один выход).

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

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

Классификация грамматик. Четыре типа грамматик по Хомскому

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

210

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

По классификации Хомского выделяют четыре типа грамматик.

Тип 0: грамматики с фразовой структурой На структуру их правил не накладывается никаких ограничений: для грамматики вида G(VT,VN,P,S), V = VNИVT правила имеют вид: a ® b, где aОV+, bОV*.

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

Практического применения грамматики, относящиеся только к типу 0, не имеют.

Тип 1: контекстно-зависимые (КЗ) и неукорачивающие грамматики

В этот тип входят два основных класса грамматик: Контекстно-зависимые грамматики G(VT,VN,P,S), V = VNИVT имеют правила вида: a1Aa2 ® a1ba2, где a1,a2ОV*, AОVN, bОV+.

Неукорачивающие грамматики G(VT,VN,P,S), V = VN И VT имеют правила вида: a ® b, где a,bОV+, |b| і |a|. Структура правил КЗ-грамматик такова, что при построении предложений заданного ими языка один и тот же нетерминальный символ может быть заменен на ту или иную цепочку символов в зависимости от того контекста, в котором он встречается. Именно поэтому эти грамматики называют “контекстно-зависимыми”. Цепочки a1 и a2 в

211

правилах грамматики обозначают контекст (a1 — левый контекст, а a2 — правый контекст), в общем случае любая из них (или даже обе) может быть пустой. Говоря иными словами, значение одного и того же символа может быть различным в зависимости от того, в каком контексте он встречается.

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

Доказано, что эти два класса грамматик эквивалентны. Это значит, что для любого языка, заданного контекстнозависимой грамматикой, можно построить неукорачивающую грамматику, которая будет задавать эквивалентный язык, и наоборот: для любого языка, заданного неукорачивающей грамматикой, можно построить контекстно-зависимую грамматику, которая будет задавать эквивалентный язык.

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

Тип 2: контекстно-свободные (КС) грамматики

Контекстно-свободные (КС) грамматики G(VT,VN,P,S), V = VNИVT имеют правила вида: A ® b, где AОVN, bОV+. Такие грамматики также иногда называют неукорачивающими контекстно-свободными (НКС)

212

грамматиками (видно, что в правой части правила у них должен всегда стоять как минимум один символ). Существует также почти эквивалентный им класс грамматик — укорачивающие контекстно-свободные (УКС) грамматики G(VT,VN,P,S), V = VNИVT, правила которых могут иметь вид: A ® b, где AОVN, bОV*. Разница между этими двумя классами грамматик заключается лишь в том, что в УКС-грамматиках в правой части правил может присутствовать пустая цепочка (l), а в НКС-грамматиках — нет. Отсюда ясно, что язык, заданный НКС-грамматикой, не может содержать пустой цепочки. Доказано, что эти два класса грамматик почти эквивалентны. В дальнейшем, когда речь будет идти о КСграмматиках, уже не будет уточняться, какой класс грамматики (УКС или НКС) имеется в виду, если возможность наличия в языке пустой цепочки не имеет принципиального значения.

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

Внутри типа КС-грамматик кроме классов НКС и УКС выделяют еще целое множество различных классов грамматик, и все они относятся к типу 2. Далее, когда КСграмматики будут рассматриваться более подробно, на некоторые из этих классов грамматик и их характерные особенности будет обращено особое внимание.

Тип 3: регулярные грамматики.

К типу регулярных относятся два эквивалентных класса грамматик: леволинейные и праволинейные. Леволинейные грамматики G(VT,VN,P,S), V = VNИVT могут иметь правила двух видов: A ® Bg или A ® g, где

213

A,BОVN, gОVT*.

В свою очередь, праволинейные грамматики G(VT,VN,P,S), V = VNИVT могут иметь правила тоже двух видов: A ® gB или A ® g, где A,BОVN, gОVT*. Эти два класса грамматик эквивалентны и относятся к типу регулярных грамматик.

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

Соотношения между типами грамматик

Типы грамматик соотносятся между собой особым образом. Из определения типов 2 и 3 видно, что любая регулярная грамматика является КС-грамматикой, но не наоборот. Также очевидно, что любая грамматика может быть отнесена к типу 0, поскольку он не накладывает никаких ограничений на правила. В то же время существуют укорачивающие КС-грамматики (тип 2), которые не являются ни контекстно-зависимыми, ни неукорачивающими (тип 1), поскольку могут содержать правила вида “A ® l”, недопустимые в типе 1.

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

214

Соседние файлы в папке GOSY