Получение следующего объекта — различия между версиями
Free0u (обсуждение | вклад) (→Пример работы) |
Korektur (обсуждение | вклад) (Добавлен раздел: "Специализация алгоритма для генерации следующего разбиения на подмножества") |
||
Строка 61: | Строка 61: | ||
|'''1'''||'''3'''||'''4'''||'''2'''||'''5'''||следующая перестановка | |'''1'''||'''3'''||'''4'''||'''2'''||'''5'''||следующая перестановка | ||
|} | |} | ||
+ | |||
+ | == Специализация алгоритма для генерации следующего разбиения на подмножества == | ||
+ | * Двигаясь снизу вверх и справа налево, будем удалять элементы, записывая их в отдельный массив. Будем повторять эту операцию, пока не выполнится одно из условий ниже: | ||
+ | |||
+ | 1) Каждый раз, рассматривая новый элемент, будем пытаться заменить его уже удаленным элементом из нашего массива, так чтобы не нарушалась возрастающая последовательность элементов в этом подмножестве. Из всех подходящих элементов выбираем минимальный. '''Важное замечание''': мы не можем заменить 1ый элемент подмножества, мы можем только удалить его. | ||
+ | |||
+ | 2) Каждый раз, переходя в новое подмножество, будем пытаться дополнить его элементом из уже удаленных, так чтобы не нарушалась возрастающая последовательность элементов этом подмножестве. Из всех подходящих элементов выбираем минимальный. | ||
+ | |||
+ | * Допишем лексикографически минимальный хвост подмножеств из оставшихся элементов. | ||
+ | |||
+ | <code> | ||
+ | // a - матрица содержащая подмножества | ||
+ | // used - массив в котором мы храним, удаленные элементы | ||
+ | for i = n - 1 downto 0 //перебираем все подмножества, начиная с последнего | ||
+ | if ( /*можем добавить в конец подмножества элемент из used*/ ){ | ||
+ | // добавляем | ||
+ | break; | ||
+ | } | ||
+ | for j = m - 1 downto 0 // перебираем все элементы текущего подмножества | ||
+ | if( /* можем заменить элемент, другим элементом из массива used*/ ){ | ||
+ | //заменяем | ||
+ | break; | ||
+ | } | ||
+ | used.add(a[i][j]); //удаляем элемент и добавляем его в массив | ||
+ | printsets(); //далее выведем все получившиеся подмножества | ||
+ | sort(used); //отсортируем массив оставшихся элементов | ||
+ | for i = 0 to used.size() do | ||
+ | println(used[i]); //выведем лексикографически минимальный хвост | ||
+ | </code> | ||
+ | |||
+ | === Пример работы === | ||
+ | |||
+ | '''Рассмотрим следующее разбиение:''' | ||
+ | {1, 2, 3} | ||
+ | {4, 5} | ||
+ | |||
+ | '''1 Шаг:''' | ||
+ | {1, 2, 3} | ||
+ | {4} | ||
+ | used = {5}; | ||
+ | |||
+ | Удалили элемент 5. | ||
+ | |||
+ | '''2 Шаг:''' | ||
+ | {1, 2, 3} | ||
+ | used = {4, 5}; | ||
+ | |||
+ | Удалили элемент 4. Так как он является первым в подмножестве, то мы не можем заменить его на другой. | ||
+ | |||
+ | '''3 Шаг:''' | ||
+ | {1, 2, 3, 4} | ||
+ | {5} | ||
+ | used = {}; | ||
+ | |||
+ | Дополнили первое подмножество элементом 4(так как он минимальный из всех элементов, которыми мы могли его дополнить), и дописали лексикографически минимальный хвост. | ||
== Ссылки == | == Ссылки == |
Версия 20:54, 19 декабря 2012
Содержание
Алгоритм
Определение: |
Получение следующего объекта — это нахождение объекта, следующего за данным в лексикографическом порядке. |
Объект
называется следующим за , если и не найдется такого , что .Отсюда понятен алгоритм:
- Находим суффикс минимальной длины, который можно изменить без изменения префикса текущего объекта
- К оставшейся части дописываем минимальный возможный элемент (чтобы было выполнено правило )
- Дописываем минимальный возможный хвост
По построению получаем, что
— минимально возможный.Специализация алгоритма для генерации следующего битового вектора
- Находим минимальный суффикс, в котором есть 0, его можно увеличить, не меняя оставшейся части
- Вместо 0 записываем 1
- Дописываем минимально возможный хвост из нулей
for i = n downto 1 if a[i] == 0 a[i] = 1 for j = i + 1 to n a[j] = 0 break
Пример работы
0 | 1 | 0 | 1 | 1 | исходный битовый вектор |
^ | находим элемент 0 (самый правый) | ||||
0 | 1 | 1 | 1 | 1 | меняем его на 1 |
0 | 1 | 1 | 0 | 0 | меняем элементы правее на нули |
0 | 1 | 1 | 0 | 0 | следующий битовый вектор |
Специализация алгоритма для генерации следующей перестановки
- Двигаясь справа налево, находим элаемент, нарушающий убывающую последовательность (в обычном порядке, слева направо, см. пример)
- Меняем его с минимальным элементом, большим нашего, стоящим правее
- Перевернем правую часть
for i = n - 1 downto 1 if a[i] < a[i + 1] // a[j] = min {a[j] > a[i], где j > i} swap(a[i], a[j]) reverse(a[i + 1] .. a[n]) break
Пример работы
1 | 3 | 2 | 5 | 4 | исходная перестановка |
^ | находим элемент, нарушающий убывающую последовательность | ||||
^ | минимальный элемент больше нашего | ||||
1 | 3 | 4 | 5 | 2 | меняем их местами |
1 | 3 | 4 | 2 | 5 | разворачивам правую часть |
1 | 3 | 4 | 2 | 5 | следующая перестановка |
Специализация алгоритма для генерации следующего разбиения на подмножества
- Двигаясь снизу вверх и справа налево, будем удалять элементы, записывая их в отдельный массив. Будем повторять эту операцию, пока не выполнится одно из условий ниже:
1) Каждый раз, рассматривая новый элемент, будем пытаться заменить его уже удаленным элементом из нашего массива, так чтобы не нарушалась возрастающая последовательность элементов в этом подмножестве. Из всех подходящих элементов выбираем минимальный. Важное замечание: мы не можем заменить 1ый элемент подмножества, мы можем только удалить его.
2) Каждый раз, переходя в новое подмножество, будем пытаться дополнить его элементом из уже удаленных, так чтобы не нарушалась возрастающая последовательность элементов этом подмножестве. Из всех подходящих элементов выбираем минимальный.
- Допишем лексикографически минимальный хвост подмножеств из оставшихся элементов.
// a - матрица содержащая подмножества // used - массив в котором мы храним, удаленные элементы for i = n - 1 downto 0 //перебираем все подмножества, начиная с последнего if ( /*можем добавить в конец подмножества элемент из used*/ ){ // добавляем break; } for j = m - 1 downto 0 // перебираем все элементы текущего подмножества if( /* можем заменить элемент, другим элементом из массива used*/ ){ //заменяем break; } used.add(a[i][j]); //удаляем элемент и добавляем его в массив printsets(); //далее выведем все получившиеся подмножества sort(used); //отсортируем массив оставшихся элементов for i = 0 to used.size() do println(used[i]); //выведем лексикографически минимальный хвост
Пример работы
Рассмотрим следующее разбиение: {1, 2, 3} {4, 5}
1 Шаг: {1, 2, 3} {4} used = {5};
Удалили элемент 5.
2 Шаг: {1, 2, 3} used = {4, 5};
Удалили элемент 4. Так как он является первым в подмножестве, то мы не можем заменить его на другой.
3 Шаг: {1, 2, 3, 4} {5} used = {};
Дополнили первое подмножество элементом 4(так как он минимальный из всех элементов, которыми мы могли его дополнить), и дописали лексикографически минимальный хвост.