генерація поєднань

генерація поєднань

В комбінаториці поєднанням з N різних елементів по M називається набір M елементів, вибраних з безлічі N елементів. Такі набори відрізняються тільки входженням в них M певних елементів, порядок проходження елементів в такому наборі не важливий. Набори, що відрізняються тільки порядком проходження елементів (але не складом), вважаються однаковими, і цим поєднання відрізняються від розміщень.

Сполучення без повторень

Завдання. Знайти всі можливі поєднання без повторень з безлічі елементів по 2.
Існують наступні поєднання:

Кількість можливих поєднань без повторень з N елементів по M можна визначити за формулою (N≥M):

що в M! раз менше відповідної кількості розміщень без повторень (оскільки поєднання без повторень не залежить від порядку проходження елементів).

Розглянемо задачу отримання всіх сполучень для чисел 1. N по M.

Реалізація на С ++

#include
using namespace std;
bool NextSet (int * a, int n, int m)
int k = m;
for (int i = k - 1; i> = 0; --i)
if (a [i] ++a [i];
for (int j = i + 1; j a [j] = a [j - 1] + 1;
return true;
>
return false;
>
void Print (int * a, int n)
static int num = 1;
cout.width (3);
cout < for (int i = 0; i cout < cout <>
int main ()
int n, m, * a;
cout <<"N = " ;
cin >> n;
cout <<"M = " ;
cin >> m;
a = new int [n];
for (int i = 0; i a [i] = i + 1;
Print (a, m);
if (n> = m)
while (NextSet (a, n, m))
Print (a, m);
>
cin.get (); cin.get ();
return 0;
>

Сполучення з повтореннями

Поєднаннями з повтореннями називаються набори по M елементів, в яких кожен елемент безлічі N може брати участь кілька разів. При цьому на співвідношення значень M і N пропустити накладається ніяких обмежень, а загальна кількість сполучень з повтореннями становить

Прикладом такого завдання може служити вибір M листівок з N всіма можливими способами.

Для генерації сполучень з повтореннями скористаємося рішенням для генерації розміщень з повтореннями, розглянутим в цій статті.

Реалізація на С ++

#include
using namespace std;
bool NextSet (int * a, int n, int m)
int j = m - 1;
while (a [j] == n j> = 0) j--;
if (j <0) return false;
if (a [j]> = n)
j--;
a [j] ++;
if (j == m - 1) return true;
for (int k = j + 1; k a [k] = a [j];
return true;
>
void Print (int * a, int n)
static int num = 1;
cout.width (3);
cout < for (int i = 0; i cout < cout <>
int main ()
int n, m, * a;
cout <<"N = " ;
cin >> n;
cout <<"M = " ;
cin >> m;
int h = n> m. n. m; // розмір масиву а вибирається як max (n, m)
a = new int [h];
for (int i = 0; i a [i] = 1;
Print (a, m);
while (NextSet (a, n, m))
Print (a, m);
cin.get (); cin.get ();
return 0;
>

Результат роботи наведеного вище алгоритму:

генерація поєднань

генерація поєднань

Схожі статті