Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Комбинаторика




9.2.1 Нахождение числа сочетаний из n по m

Функция находит число сочетаний из n элементов по m:

 

Вычисления проводятся по рекуррентной формуле:

 

 

//*****************************************************************

//Функция находит число сочетаний C из n по m.

//*****************************************************************

int combinationsnm (int n, int m)

{

int result;

int i;

 

if(n<m)

{

result = 0;

}

else

{

if(m>double(n)/double(2))

{

m = n-m;

}

if(m==0)

{

result = 1;

}

else

{

n = n+1;

result = 1;

i = 1;

do

{

result = result*(n-i)/i;

i = i+1;

}

while(i<=m);

}

}

return result;

}

 

9.2.2 Генерация перестановки, следующей за данной

 

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

Количество перестановок из n чисел будет равно факториалу числа n.

 

 

// ******************************************************************

char NextPermutation(int n; int& x[]);

 

Процедура находит перестановку следующую за данной в

лексикографическом порядке. Начальная перестановка

задается в массиве X, туда же после работы процедуры

помещается найденная перестановка.

 

Скажем, для N равного 3 существуют шесть

перестановок:

№1: 1 2 3

№2: 1 3 2

№3: 2 1 3

№4: 2 3 1

№5: 3 1 2

№6: 3 2 1

 

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

Таким образом чтобы получить все перестановки n - чисел надо инициализировать массив X значениями 1,2,..., n и последовательно вызывать процедуру до тех пор пока результат не окажется равным истине.

 

Количество перестановок из n чисел будет равно факториалу числа n.

*************************************************************************/

bool nextpermutation(int n, int& x[])

{

bool result;

int k;

int t;

int y;

 

k = n-1;

while(k>0)

{

if(x[k]<=x[k+1])

{

break;

}

k = k-1;

}

if(k!=0)

{

t = k+1;

while(t<n)

{

if(x[t+1]<=x[k])

{

break;

}

t = t+1;

}

y = x[k];

x[k] = x[t];

x[t] = y;

t = 0;

while(t<(n-k)/2)

{

y = x[n-t];

x[n-t] = x[k+1+t];

x[k+1+t] = y;

t = t+1;

}

result = false;

}

else

{

result = true;

}

return result;

}

 

 

9.2.3 Генерация перестановки по номеру

 

Этот алгоритм предназначен для получения перестановки по её номеру (перестановки упорядочены в лексикографическом порядке). В оющем случае, чтобы получить перестановку с номером K, можно вызвать K раз алгоритм получения следующей перестановки. Если требуется последовательно получать перестановки с номерами от 1 до K, то можно поступить и так, но в случае, когда требуется получить лишь K-ую перестановку, но такой способ крайне неэффективен. Для этого можно использовать специальный алгоритм, который позволяет непосредственно получить искомую перестановку без всяких промежуточных шагов.

 

//******************************************************************

KthPermutation(int n; int k; int &a[]);

 

процедура находит K-ую из перестановок чисел от 1 до N, упорядоченных в лексикографическом порядке. Перестановки нумеруются от 1 до N!.

 

Скажем, для N равного 3 существуют шесть

перестановок:

№1: 1 2 3

№2: 1 3 2

№3: 2 1 3

№4: 2 3 1

№5: 3 1 2

№6: 3 2 1

 

Число N должно быть достаточно мало, чтобы

N! уместилось в разрядную сетку компьютера.

*************************************************************************/

void kthpermutation(int n, int k, int &a[])

{

int temp;

int selnum;

int i;

int j;

int f;

 

k = k-1;

f = 1;

a.setbounds(1, n);

for(i = 1; i <= n; i++)

{

a[i] = i;

f = f*i;

}

for(i = 1; i <= n-1; i++)

{

f = f/(n+1-i);

selnum = i+k/f;

temp = a[selnum];

for(j = selnum; j >= i+1; j--)

{

a[j] = a[j-1];

}

a[i] = temp;

k = k%f;

}

}

 

9.2.4 Получение номера перестановки

 

Этот алгоритм позволяет по перестановке чисел от 1 до N получить её номер в списке перестановок, упорядоченных в лексикографическом порядке.

 

// ******************************************************************

// int permutationnum(int n, int& a[]);

// процедура находит порядковый номер перестановок чисел

// от 1 до N, упорядоченных в лексикографическом порядке.

// Перестановки нумеруются от 1 до N!.

 

// Скажем, для N равного 3 существуют шесть перестановок:

// №1: 1 2 3

// №2: 1 3 2

// №3: 2 1 3

// №4: 2 3 1

// №5: 3 1 2

// №6: 3 2 1

 

// Число N должно быть достаточно мало, чтобы N!

// уместилось в разрядную сетку компьютера.

//******************************************************************

int permutationnum(int n, int& a[])

{

int result;

int t;

int i;

int j;

int f;

 

result = 0;

f = 1;

for(i = 1; i <= n; i++)

{

f = f*i;

}

for(i = 1; i <= n-1; i++)

{

f = f/(n+1-i);

t = a[i]-1;

for(j = 1; j <= i-1; j++)

{

if(a[j]<a[i])

{

t = t-1;

}

}

result = result+f*t;

}

result = result+1;

return result;

}

 

9.2.5 Генерация выборки из n по m, следующей за данной

 

Функция находит выборку, следующую за данной в лексикографическом порядке. Начальная выборка задается в массиве X, туда же после работы функции помещается найденная выборка. Результат функции равен истине, если на вход подана выборка являющаяся последней при лексикографическом упорядочивании. Таким образом чтобы получить все выборки - надо инициализировать массив X значениями 1, 2,..., m и последовательно вызывать функцию до тех пор пока результат не окажется равным истине. Числа внутри выборки, поданной на вход функции, должны быть упорядочены по возрастанию.

 

/*************************************************************************

Выборки из n элементов по m.

 

char nextretrieval(int n, int m, int &x[]);

 

процедура находит выборку следующую в лексикографическом порядке за выборкой заданной в массиве X. Если выборка в массиве последняя, то переменной Result присваивается значение True, иначе False.

 

Числа в сочетании упорядочены по возрастанию.

 

Скажем, для N=3, M=2 существуют три комбинации:

№1: 1 2

№2: 1 3

№3: 2 3

 

Таким образом чтобы получить все выборки из n по m, надо

инициализировать массив X значениями 1,2,..., m и последовательно

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

 

Количество выборок будет равно числу сочетаний из n по m.

*************************************************************************/

 

char nextretrieval(int n, int m, int &x[])

{

bool result;

int i;

 

result = false;

i = m;

while(i>0)

{

if(x(i)<n-(m-i))

{

break;

}

i = i-1;

}

if(i>0)

{

x(i) = x(i)+1;

i = i+1;

while(i<=m)

{

x(i) = x(i-1)+1;

i = i+1;

}

}

else

{

result = true;

}

return result;

}

 

9.2.5 Генерация выборки по номеру

 

Этот алгоритм предназначен для получения выборки (комбинации, сочетания) из N по M по её номеру (выборки упорядочены в лексикографическом порядке). В принципе, чтобы получить выборку с номером K, можно вызвать K раз алгоритм получения следующей выборки. Если требуется последовательно получать выборки с номерами от 1 до K, то можно поступить и так, но в случае, когда требуется получить лишь K-ую выборку, но такой способ крайне неэффективен. Для этого можно использовать специальный алгоритм, который позволяет непосредственно получить искомую выборку без всяких промежуточных шагов. Под выборкой в данном случае понимается упорядоченный массив из M неповторяющихся чисел в диапазоне от 1 до N включительно.

 

/*************************************************************************

void kthretrieval(int n, int m, int k, int &a[])

 

Эта процедура по номеру комбинации из N по M строит саму комбинацию, имеющую номер K. Комбинации упорядочены в лексикографическом порядке и имеют номера от 1 до C(n,m)

 

Числа в сочетании упорядочены по возрастанию.

 

Скажем, для N=3, M=2 существуют три комбинации:

№1: 1 2

№2: 1 3

№3: 2 3

 

Числа N и M должны быть достаточно малы, чтобы C(n,m)

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

*************************************************************************/

 

 

void kthretrieval(int n, int m, int k, int &a[])

{

int i;

int j;

int lbound;

int c;

int t;

 

a.setbounds(1, m);

if(n==1||n==m)

{

for(i = 1; i <= m; i++)

{

a[i] = i;

}

return;

}

if(m==1)

{

a[1] = k;

return;

}

t = 1;

lbound = 1;

c = 1;

for(i = 1; i <= m-1; i++)

{

c = c*(n-i)/i;

}

for(i = 1; i <= m-1; i++)

{

for(j = lbound+1; j <= n; j++)

{

if(t+c>k)

{

a[i] = j-1;

break;

}

t = t+c;

c = c*(n-j+1-m+i)/(n-j+1);

}

c = c*(m-i)/(n-a(i));

lbound = a[i]+1;

}

a[m] = lbound+k-t;

}

 

9.2.6 Получение номера выборки

 

Ещё один алгоритм для работы с выборками. Этот алгоритм позволяет по выборке из N по M получить её номер в списке выборок, упорядоченных в лексикографическом порядке. Под выборкой в данном случае понимается упорядоченный массив из M неповторяющихся чисел в диапазоне от 1 до N включительно

 

/*************************************************************************

int retrievalnum(int n, int m, int &a[]);

 

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

Числа от 1 до N. Нумерация идет от 1 до C(N,M).

 

Числа в сочетании должны быть упорядочены по возрастанию.

 

Скажем, для N=3, M=2 существуют три сочетания:

№1: 1 2

№2: 1 3

№3: 2 3

 

Числа N и M должны быть достаточно малы, чтобы C(n,m)

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

*************************************************************************/

 

 

int retrievalnum(int n, int m, int &a[]);

{

int result;

int i;

int j;

int lbound;

int c;

 

if(n==1||n==m)

{

result = 1;

return result;

}

if(m==1)

{

result = a[1];

return result;

}

result = 1;

lbound = 1;

c = 1;

for(i = 1; i <= m-1; i++)

{

c = c*(n-i)/i;

}

for(i = 1; i <= m-1; i++)

{

for(j = lbound+1; j <= a[i]; j++)

{

result = result+c;

c = c*(n-j+1-m+i)/(n-j+1);

}

c = c*(m-i)/(n-a[i]);

lbound = a[i]+1;

}

result = result+a(m)-lbound;

return result;

}

 




Поделиться с друзьями:


Дата добавления: 2014-10-17; Просмотров: 653; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.074 сек.