Существует важное наблюдение (в комментарии), что разбиение множества n
элементов могут быть представлены в виде целого последовательности форма [p , & hellip; р п], где р я это номер раздела элемента я. Для такой последовательности, чтобы быть действительным, он должен подчиняться правилам, которые р является 1, и для каждого J где 1 < J ≤ п, есть некоторые я < J такое, что р J≤ рi + 1. Или, другими словами, в любом префиксе последовательности никакое целое число не пропускается.
В настоящее время, существует стандартный алгоритм для перечисления ограниченных последовательностей в лексикографическом порядке, который состоит из следующих действий:
- Start с наименьшей последовательности.
- Чтобы найти следующую последовательность в лексикографическом порядке:
- сканирование в обратном направлении по последовательности и найти самый правый «incrementable» элемент. (Инкрементный элемент - это такой элемент, что существует некоторый более крупный элемент, который может быть заменен для этого элемента, а полученная подпоследовательность до этой точки является префиксом по меньшей мере одной допустимой последовательности.)
- Измените этот элемент на следующий более крупный элемент, который является жизнеспособным (т. е. приводит к действительному префиксу, как указано выше), а затем заполняет оставшиеся элементы справа (если есть) с наименьшими возможными значениями.
- Если нет добавочного элемента, то перечисление завершается.
С несколькими положениями о поиске в incrementable элемента, этот алгоритм в худшем случае O (п) и часто O(), когда элемент будет увеличиваться, как правило, близка до конца последовательности. (Например, использование этого алгоритма для перечисления перестановки - это O (1), чтобы найти следующую перестановку, если вы можете найти «следующий элемент» в O (1).)
Чтобы применить этот алгоритм к мы наблюдаем следующее:
- Наименьшая возможная последовательность [1, & hellip; 1]
- Элемент ря является incrementable при условии, что:
- ря < н
- Существует несколько J < я такой, что pi & equals; рJ
- Самый маленький суффикс жизнеспособного префикса [1, & hellip; 1]
Другой способ задания состояния при наблюдении 2 является то, что элемент является incrementable, если его значение не п или это первый элемент в последовательности с ее значением.Мы можем сделать это определение в O (1), если мы также сохраним последовательность [m , & hellip; м п], где м равно 0, а м я это максимум мя -1 и ря -1. м тривиально поддерживать, и это позволяет нам переписать условие incrementability как просто ря ≤ мя.
Легко видеть, что Следующая Partition могут быть реализованы в O (п) времени, но, как это бывает и так, что он амортизируется время O (1). Грубо говоря, это потому, что в большинстве случаев последний элемент последовательности является инкрементальным.
Подсказка: предположим, что у вас есть весь набор всех разделов {1, ..., n-1}. (BTW, отдельные наборы в разделе обычно называются «частями».) Есть ли способ генерировать каждый раздел из {1, ..., n} из них, введя элемент n в каждый раздел так или иначе? Будет ли это генерировать каждый раздел {1, ..., n} один раз и только один раз? –
Я думаю, что вы правы, но я не мог понять точный алгоритм. Например, если я хочу сгенерировать все разделы 'A_3 = {1, 2, 3}', тогда мне нужно найти способ вставить '3' во все разделы' A_2 = {1, 2} '. Затем разделы 'A_2' являются' {1, 2} 'и' {1} {2} '. До сих пор я прав? И для больших значений, 'A_4', я должен вставить' 4' во все разделы 'A_3', а затем вставить' 3' во все разделы 'A_2'? – cristid9
Да, вы правы до сих пор. Две вещи, которые следует помнить: 1. Когда раздел содержит более одной части (например, '{1} {2}' в вашем примере), вам нужно попробовать добавить новый элемент в каждую часть - так что вы создадите совершенно новый * раздел * для каждого * часть *. 2. Вам также необходимо создать разделы, в которых новый номер находится в отдельной части. –