Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
дискретка / diskr / combgraph / combgraph.pdf
Скачиваний:
131
Добавлен:
26.05.2014
Размер:
2.03 Mб
Скачать

§ 6. Порождение сочетаний и перестановок.

1.Рассмотрим теперь алгоритмические вопросы, связанные с порождением сочетаний и перестановок. Пусть дано множество А = {1, 2, … , n}.

Порождение сочетаний. Приведем алгоритм, порождающий все сочетания (подмножества) множества А.

Алгоритм “сочетания”.

1.Дано: множество А. Выход: последовательность подмножеств А.

2.Начало: Пустое множество .

3.Пусть порождено множество S. Тогда следующее множество Sполучается включением в S наименьшего элемента, не принадлежащего S, и удалением из него всех элементов, меньших включенного. Если таких элементов нет, стоп.

Справедливость алгоритма следует индукцией по n, если заметить, что алгоритм порождает сначала все подмножества множества A= {1, 2, , n - 1}, затем повторяет эту последовательность, добавляя к каждому подмножеству n. Последним членом в последовательности будет само множество А, и алгоритм автоматически остановится. Укажем теперь алгоритм, который порождает все подмножества множества А, так, что каждое следующее отличается от предыдущего не более, чем на один элемент.

Данный алгоритм определим индуктивно.

Алгоритм “Сочетания добавлением/изъятием одного элемента”.

Если n = 1, то выход алгоритма есть последовательность , {1}.

Пусть для n - 1 выходом алгоритма есть последовательность Ln-1 . Обозначим

Ln1 - последовательность Ln-1, написанную в обратном порядке. Тогда для n выходом алгоритма будет последовательность

Ln = Ln-1 , Ln1 {n},

где Ln1 {n}означает, что к каждому члену последовательности Ln1 добавлен эле-

мент n.

Пример: L2 = , {1}, {1, 2}, {2}

L3 = , {1}, {1, 2}, {2}, {2, 3}, {1, 2, 3}, {1, 3}, {3}.

Справедливость алгоритма легко устанавливается индукцией по n, если заметить, что Ln-1 заканчивается множеством {n - 1}. Первая половина последовательности Ln совпадает с Ln-1 и по индукции удовлетворяет нужным требованиям. Следующий элемент после Ln-1 есть {n - 1, n}, и затем проходится последовательность Ln-1 в обратном порядке с

38

добавлением элемента {n}, и нужные требования снова выполняются. Поскольку первый элемент в Ln-1 есть , то последний элемент в Ln есть {n}. Если длина Ln-1 есть 2n-1 , то длина Ln есть

2 2n-1 = 2n .

Представим теперь алгоритм, который порождает все r-сочетания n-множества

А = {1, 2, … , n} в лексикографическом порядке. Каждое r-сочетание представляется числами a1 < a2 < … < ar.

Начало алгоритма: a1 = 1, a2 = 2, … , ar = r.

Пусть порождено r-сочетание a1, a2, … , ar . Тогда определяется наибольшее ai, такое, что ai + 1 не входит в данное сочетание. Если таких ai нет (это происходит только в случае a1 = n - r + 1, … , ar = n ), то стоп.

Если такое a

i

есть, то образуем новое сочетание a

,K,a

, полагая

 

 

 

 

 

 

 

 

 

 

 

 

1

 

 

 

 

r

a = a

,K,a

 

= a

i1,

a

= a

i

+1,a

i+1

= a

i

+ 2,K,a

r

= a

i

+ r i .

1

1

 

 

i1

r

 

 

 

 

 

 

Проиллюстрируем алгоритм для n = 4, r = 2

 

 

 

 

 

 

 

 

 

 

Шаги

 

 

Сочетания

 

ai

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1

 

 

 

 

1,2

 

 

 

2

 

 

 

 

 

 

 

 

 

2

 

 

 

 

1,3

 

 

 

3

 

 

 

 

 

 

 

 

 

3

 

 

 

 

1,4

 

 

 

1

 

 

 

 

 

 

 

 

 

4

 

 

 

 

2,3

 

 

 

3

 

 

 

 

 

 

 

 

 

5

 

 

 

 

2,4

 

 

 

2

 

 

 

 

 

 

 

 

 

6

 

 

 

 

3,4

 

 

 

стоп

 

 

 

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

2. Перейдем теперь к вопросу порождения n-перестановок

n-множества А = {1, 2, … , n}. Определим сначала индуктивный алгоритм А(n). Для n = 1 выход А(1) есть перестановка (1). Пусть для n - 1 алгоритм построил все (n - 1)- перестановки чисел 1, 2, … , n - 1. Тогда А(n) действует так.

Каждой (n - 1)-перестановке b1, … , bn-1 чисел 1, 2, … , n - 1 ставится в соответствие n перестановок чисел 1, 2, … , n следующим образом:

(b1,K,bn1

,1) ,

где bi

= bi

+1, i =

 

 

1, n 1

(b′′,K,b′′

,2) ,

где b′′= b

i

если b

i

= 1

 

1

n1

 

i

 

 

 

 

 

39

 

 

b′′

= b

i

+ 2

 

если b

i

2.

 

 

i

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

(b(n) ,K,bn

,n) , где b(n) = b

 

i =

 

 

,

1, n 1

1

n1

 

i

 

i

 

 

 

 

 

 

Корректность данного алгоритма следует из того, что для любого s

1, n

последова-

тельность

b(s) ,K,b(s)

есть перестановка чисел 1, 2, … , s - 1, s + 1, … , n.

 

1

n1

 

 

 

Представим теперь алгоритм порождения всех n! перестановок n-множества

А = {1, 2, … , n} , в котором переход от одной перестановки к следующей осуществляется одной транспозицией соседних элементов. Транспозиция - это перемена местами двух элементов. Каждый элемент снабжается “направлением”, обозначаемым ““ или ““. Число k называется подвижным, если существует меньшее его число, соседнее с ним со стороны стрелки.

Алгоритм “Перестановки”.

← ← ←

Начало - конфигурация 1 2 ... n

Шаг алгоритма

1.Если нет подвижных элементов, то стоп.

2.Находится наибольшее подвижное число m

3. Число m переставляется с соседним элементом, на которое указывает направление m.

4.Направления всех элементов k, k > m меняются на противоположные.

5.Повторить шаг 1.

Проиллюстрируем алгоритм для n = 3.

Шаг

Конфигурация

Максимальное

1

 

подвижное число

← ← ←

3

 

1 2 3

 

2

← ← ←

3

 

1 3 2

 

3

← ← ←

2

 

3 1 2

 

4

→ ← ←

3

 

3 2 1

 

5

← → ←

3

 

2 3 1

 

40

6 нет, стоп

← ← →

2 1 3

41

Корректность данного алгоритма устанавливается индукцией по n. Пусть алгоритм правильно работает для n, и покажем его правильность для n + 1. (Случай n = 1

← ← ←

тривиален). Ясно, что если начинать работу с конфигурации 1 2 ... n n +1 , что n + 1 -

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

← ← ←

конфигурация n +1 1 ... n . При этом будут порождены n+1 перестановок, в которых число n+1 занимает места n + 1, n, … , 1. Теперь максимальное подвижное число n, и переставляются элементы множества 1, 2, … ,n. Теперь снова максимальное подвижное число n + 1, после смены его направления оно будет двигаться влево n + 1 раз, порождая

n + 1 перестановок. Когда будет получена перестановка a1 a2 … an n +1 , число n+1 не будет неподвижным, и алгоритм будет применяться к множеству

1, 2, …n, после чего число n + 1 снова становится подвижным. Таким образом, алгоритм порождает n + 1 перестановок и применяется к множеству 1, 2, … , n. Когда будет достигнута последняя перестановка чисел 1, 2, … , n, то число n +1 через n + 1 шагов перестанет быть подвижным, и алгоритм останавливается. Общее число шагов алгоритма

(n + 1) n! = (n + 1)!.

42