Помогите, пожалуйста, решить следующую задачу.
Имеется множество
перенумерованных объектов (их количество
). Из этого множества выбирается подмножество
. Требуется составить некоторую функцию (некоторое соответствие), которая перенумеровывала бы все возможные подмножества
. То есть, при фиксированном
, каждому подмножеству сопоставить некоторое целое число. Причём, если подмножества разные, то сопоставляемые им числа так же должны быть разными (обратимость функции), а если в одном подмножестве элементов больше, чем во втором, то его номер должен быть больше номера второго соответственно.
Очевидно, что количество всех способов выбрать подмножество
из множества
будет равно
(включая сюда пустое подмножество
). Логично тогда перенумеровать все комбинации подмножеств
числами от 0 до
. Каждому биту этого номера поставить в соответствие один элемент исходного множества
и, если этот бит равен единице, то потребовать, чтобы этот элемент принадлежал подмножеству
. При такой нумерации подмножеств числу
будет соответствовать пустое подмножество, числу
— подмножество состоящее из всего множества
, числам
, где
от
до
— подмножества из, соответственно, единственного элемента с номером
(если считать, что элементы множества
нумеруются от
до
). И всё бы хорошо, но...
Но эта нумерация не удовлетворяет требованию
Цитата:
если в одном подмножестве элементов больше, чем в другом, то его номер должен быть больше номера второго соответственно
Например, при указанной выше нумерации подмножество номер
состоит из одного элемента (номер
), а подмножество номер
состоит из трёх элементов исходного множества с номерами
,
и
.
Первый шар на пути к решению, если я не ошибаюсь, это вспомнить биномиальные коэффициенты. Количество пустых подмножеств равно единице, количество подмножеств из одного элемента —
, количество подмножеств из двух элементов —
и так далее. Для подмножества из
элементов —
. Сумма всех этих чисел равна
. Можно записать отдельно для подмножеств из фиксированного числа
элементов все возможные выборки. Номера выбираемых элементов записать в порядке возрастания, все записи отсортировать в порядке возрастания их позиционной записи, а затем все эти последовательности для разных
записать друг за другом в порядке возрастания
и перенумеровать от
до
. Получится что-то типа этого:
Код:
0 ничего
1 1
2 2
3 3
4 4
5 1, 2
6 1, 3
7 1, 4
8 2, 3
9 2, 4
10 3, 4
11 1, 2, 3
12 1, 2, 4
13 1, 3, 4
14 2, 3, 4
15 1, 2, 3, 4
И всё бы хорошо, но...
Но эта нумерация очень неудобна в плане вычисления обратной функции. То есть если ввести функцию, которая по заданному числу элементов исходного множества
, заданному номеру комбинации
и заданному номеру элемента
исходного множества будет возвращать единицу или ноль в случае, когда, соответственно, этот элемент
принадлежит подмножеству с номером
, то эта функция будет весьма трудоёмко и некрасиво выражаться через числа
,
и
. Вспомните ту красоту для самой первой приведённой мной комбинации: обратная функция возвращает бит с номером
в двоичной записи числа
.
И так вопрос: как надо перенумеровать все комбинации, чтобы обратная функция вычислялась бы красиво и просто.