Получение номера по объекту — различия между версиями
 (→Битовые вектора)  | 
				YanaZimka (обсуждение | вклад)   (Изменены псевдокоды для перестановок и для бинарных векторов и некоторые пунктуационные и грамматические ошибки.)  | 
				||
| Строка 7: | Строка 7: | ||
   numOfObject = 0                             |    numOfObject = 0                             | ||
   '''for''' i = 1 '''to''' n '''do'''                        ''// перебираем элементы комбинаторного объекта''  |    '''for''' i = 1 '''to''' n '''do'''                        ''// перебираем элементы комбинаторного объекта''  | ||
| − |      '''for''' j = 1 '''to''' a[i] - 1 '''do'''               ''// перебираем элементы которые в лексикографическом порядке меньше рассматриваемого''  | + |      '''for''' j = 1 '''to''' a[i] - 1 '''do'''               ''// перебираем элементы, которые в лексикографическом порядке меньше рассматриваемого''  | 
       '''if''' элемент j можно поставить на i-e место  |        '''if''' элемент j можно поставить на i-e место  | ||
         '''then''' numOfObject += d[i][j]  |          '''then''' numOfObject += d[i][j]  | ||
| Строка 19: | Строка 19: | ||
*was[1..n] {{---}} использовали ли мы уже эту цифру в перестановке.  | *was[1..n] {{---}} использовали ли мы уже эту цифру в перестановке.  | ||
| − |    '''for''' i = 1 '''to''' n '''do'''   | + |    '''for''' i = 1 '''to''' n '''do'''                       ''// n - количество цифр в перестановке''  | 
| − |      '''for''' j = 1  '''to''' a[i] - 1 '''do'''   | + |      '''for''' j = 1  '''to''' a[i] - 1 '''do'''             ''// перебираем элемент, лексикографически меньший нашего, который может стоять на i-м месте    | 
| − |        '''if''' was[j] == false                    ''// если элемент j ранее не был использован  | + |        '''begin'''  | 
| − | + |         '''if''' was[j] == false                    ''// если элемент j ранее не был использован  | |
| − | + |           '''then''' numOfPermutation += P[n - i]   ''// все перестановки с префиксом длиной i-1 равным нашему, и i-й элемент у которых меньше    | |
| − | + |       '''end'''                             ''   нашего в лексикографическом порядке идут раньше данной перестановки                  | |
| + |       was[a[i]] = true                       ''// i-й элемент использован               | ||
Данный алгоритм работает за <tex>O(n ^ 2) </tex>.  | Данный алгоритм работает за <tex>O(n ^ 2) </tex>.  | ||
| Строка 35: | Строка 36: | ||
*bitvector[1..n] {{---}} данный вектор.  | *bitvector[1..n] {{---}} данный вектор.  | ||
  '''for''' i = 1 '''to''' n '''do'''                                            |   '''for''' i = 1 '''to''' n '''do'''                                            | ||
| − |    '''if''' bitvector[i] == 1    | + |    '''if''' bitvector[i] == 1     | 
| − | + |     numOfBitvector += Pow(2,n - i)           | |
| − | |||
== См. также ==  | == См. также ==  | ||
Версия 18:15, 28 ноября 2013
Описание алгоритма
Номер данного комбинаторного объекта равен количеству меньших в лексикографическом порядке комбинаторных объектов (нумерацию ведём с 0). Все объекты меньшие данного можно разбить на непересекающиеся группы по длине совпадающего префикса. Тогда количество меньших объектов можно представить как сумму количеств объектов у которых префикс длины совпадает, а элемент лексикографически меньше -го в данном объекте (). Следующий алгоритм вычисляет эту сумму
- numOfObject — искомый номер комбинаторного объекта.
 - a[1..n] — данный комбинаторный обьект.
 - d[i][j] - (количество комбинаторных объектов с префиксом от 1 до равным данному и с -м элементом равным )
 
 numOfObject = 0                          
 for i = 1 to n do                        // перебираем элементы комбинаторного объекта
   for j = 1 to a[i] - 1 do               // перебираем элементы, которые в лексикографическом порядке меньше рассматриваемого
     if элемент j можно поставить на i-e место
       then numOfObject += d[i][j]
Сложность алгоритма — , где - количество различных элементов, которые могут находиться в данном комбинаторном объекте. Для битового вектора : возможны только 0 и 1. Количества комбинаторных объектов с заданными префиксами считаются известными, и их подсчет в сложности не учитывается. Приведем примеры способов получения номеров некоторых из комбинаторных объектов по данному объекту.
Перестановки
Рассмотрим алгоритм получения номера в лексикографическом порядке по данной перестановке размера .
- P[1..n] — количество перестановок данного размера.
 - a[1..n] — данная перестановка.
 - was[1..n] — использовали ли мы уже эту цифру в перестановке.
 
 for i = 1 to n do                       // n - количество цифр в перестановке
   for j = 1  to a[i] - 1 do             // перебираем элемент, лексикографически меньший нашего, который может стоять на i-м месте 
     begin
       if was[j] == false                    // если элемент j ранее не был использован
         then numOfPermutation += P[n - i]   // все перестановки с префиксом длиной i-1 равным нашему, и i-й элемент у которых меньше 
     end                                нашего в лексикографическом порядке идут раньше данной перестановки               
     was[a[i]] = true                       // i-й элемент использован            
Данный алгоритм работает за .
Битовые вектора
Рассмотрим алгоритм получения номера в лексикографическом порядке данного битового вектора размера . Количество битовых векторов длины — . На каждой позиции может стоять один из двух элементов, независимо от того, какие элементы находятся в префиксе, поэтому поиск меньших элементов можно упростить до условия:
- numOfBitvector — искомый номер вектора.
 - bitvector[1..n] — данный вектор.
 
for i = 1 to n do if bitvector[i] == 1 numOfBitvector += Pow(2,n - i)
См. также
- Программирование в алгоритмах / С. М. Окулов. — М.: БИНОМ. Лаборатория знаний, 2002. стр.31