Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Алгоритмы и структуры данных.doc
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
1.14 Mб
Скачать

5.2Генерация m -элементных подмножеств множества натуральных чисел

Число всех m–элементных подмножеств n–элементного множества обозначается как

или

и вычисляется по формуле

Алгоритм нечувствителен к содержимому исходного множества, но для примера будем рассматривать множество из последовательности натуральных чисел, например, 1, 2, 3, 4, 5, 6. Тогда каждому m -элементному подмножеству, например m = 4, взаимно однозначно соответствует возрастающая последовательность длины m, например, 1, 2, 4, 6.

Представим очередность получения подмножеств в следующем виде:

1 2 3 4

1 2 3 5

1 2 3 6

1 2 4 5

1 2 4 6

1 2 5 6

1 3 4 5

1 3 4 6

1 3 5 6

1 4 5 6

2 3 4 5

2 3 4 6

2 3 5 6

2 4 5 6

3 4 5 6

Пусть очередная последовательность располагается в массиве B[1..4]. Из приведенного примера можно вывести закономерность, согласно которой каждая следующая последовательность отличается от предыдущей последовательности. Для этого рассмотрим несколько пар последовательностей.

Рассмотрим следующую пару последовательностей:

1 2 3 4

1 2 3 5

Видно, что новая последовательность получена из старой последовательности, где для i=13 выполняется условие b'i = bi и b'4=b4+1

b'1, b'2, b'3, b'4 = b1, b2, b3, b4+1

Теперь рассмотрим пару последовательностей:

1 2 4 6

1 2 5 6

Видно, что новая последовательность получена из старой последовательности, где для i=12 выполняется условие b'i = bi и b'3=b3+1, b'4=b3+2.

b'1, b'2, b'3, b'4 = b1, b2, b3+1, b3+2

И, наконец, рассмотрим пару последовательностей:

1 2 5 6

1 3 4 5

Видно, что новая последовательность получена из старой последова­тельности, где выполняется условие b'1 = b1, b'2=b2+1, b'3=b2+2, b'4=b2+3.

b'1, b'2, b'3, b'4 = b1, b2+1, b2+1, b3+2

В общем случае, последовательность b'1, b'2, …, b'm, следующая непосредственно за последовательностью b1, b2, …, bm определяется следующим образом

b'1, b'2, …, b'm( = (b1, …, bq-1, bq+1, bq+2, …, bq+m-q+1(

где

q = m, если bm < n

q = p - 1, если bm = n, где p = max{i: bi < n – m + 1}

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

program M_SubSetN;

{Генерирует все M-элементные подмножества множества 1, 2, 3, ..., N-1, N}

uses crt;

const N = 6;

Var m: integer; {Размер подмножества}

B: array [1..N] of integer;

procedure M_SubSet (M: integer);

Var I, j, p: integer;

begin

for J := 1 to M do B[J] := J; {первое подмножество}

P := M;

while P >= 1 do

begin

Write (' ');

for J := 1 to M do Write (' ', B[J]); {Вывод подмножества}

Writeln;

if A[M] = N then

P := P - 1

else

P := M;

if P >= 1 then

for I := M downto P do

B[I] := B[P] + I - P + 1;

end;

end; {M_SubSet}

begin

Clrscr;

Writeln('Введите размер подмножества -> ', M);

M_SubSet(M);

end.

5.3Генрация k-компонентных выборок на множестве {0, 1}

Можно предложить и другой способ генерации всех k–компонентных подмножеств некоторого множества из N элементов. Для этого можно создать N -элементный массив-маску GB[1..N]. Элементы этого массива определяются на множестве {0, 1}. Набор нулей или единиц может выступать маской исходного множества. Тогда задача генерации всех k–компонентных подмножеств некоторого множества сводится к генерации всех возможных перестановок элементов массива GB, содержащего k единиц или m=N-k нулей. Каждая такая перестановка выступает в виде отдельного кортежа.

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

Таблица 4.1

Кортеж

p

z

0 0 1 1 1

3

0

0 1 0 1 1

2

0

0 1 1 0 1

1

0

0 1 1 1 0

0

1

1 0 0 1 1

2

0

1 0 1 0 1

1

0

1 0 1 1 0

0

1

1 1 0 0 1

1

0

1 1 0 1 0

1

1

1 1 1 0 0

3

2

Эти кортежи расположены в лексикографическом порядке. Каждый очередной кортеж может быть представлен в таком виде:

N – p – z - 1 произвольных разрядов; нуль; p единиц; z нулей.

А каждый следующий кортеж преобразуется к кортежу вида:

N – p – z - 1 произвольных разрядов; единица; z+1 нулей; p-1 единиц.

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

program SubSetMN_01;

{Программа поочередно генерирует все N-компонентные выборки на множестве /0, 1/ из некоторой N-компонентной выборки с заданным количеством нулей M, например 01010, т.е. перебирает все возможные перестановки этой выборки 00110, 10001 и т.д. Если исходная выборка содержит M нулей, то из нее можно построить C(N,M) различных упорядочений с M нулями. В исходном состоянии массив GB заполняется нулями. После каждого вызова процедуры SubSet выводится очередная выборка. Признак Finish служит для предотвращения возможной повторяемости выборок}

uses crt;

const N = 5;

type Arr = array [1..N] of integer;