<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Irdkwmnsb</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Irdkwmnsb"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/Irdkwmnsb"/>
		<updated>2026-06-11T18:40:57Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D1%81%D0%BB%D0%B5%D0%B4%D1%83%D1%8E%D1%89%D0%B5%D0%B3%D0%BE_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%B0&amp;diff=77069</id>
		<title>Получение следующего объекта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D1%81%D0%BB%D0%B5%D0%B4%D1%83%D1%8E%D1%89%D0%B5%D0%B3%D0%BE_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%B0&amp;diff=77069"/>
				<updated>2021-01-09T16:57:51Z</updated>
		
		<summary type="html">&lt;p&gt;Irdkwmnsb: /* Специализация алгоритма для генерации следующего разбиения на подмножества */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Алгоритм ==&lt;br /&gt;
{{Определение|definition= '''Получение следующего объекта''' {{---}} это нахождение объекта, следующего за данным в [[Лексикографический порядок|лексикографическом порядке]].&lt;br /&gt;
}}&lt;br /&gt;
Объект &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; называется следующим за &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;P &amp;lt; Q&amp;lt;/tex&amp;gt; и не найдется такого &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt;, что &amp;lt;tex&amp;gt;P &amp;lt; R &amp;lt; Q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Отсюда понятен алгоритм:&lt;br /&gt;
* находим суффикс минимальной длины, который можно изменить без изменения префикса текущего объекта &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* к оставшейся части дописываем минимальный возможный элемент (чтобы было выполнено правило &amp;lt;tex&amp;gt;P &amp;lt; Q&amp;lt;/tex&amp;gt;),&lt;br /&gt;
* дописываем минимальный возможный хвост.&lt;br /&gt;
По построению получаем, что &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; {{---}} минимально возможный.&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующего битового вектора ==&lt;br /&gt;
* Находим минимальный суффикс, в котором есть &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, его можно увеличить, не меняя оставшейся части&lt;br /&gt;
* Вместо &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; записываем &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; &lt;br /&gt;
* Дописываем минимально возможный хвост из нулей&lt;br /&gt;
 '''int[]''' nextVector('''int[]''' a): &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} длина вектора&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''while''' (n &amp;gt;= 0) '''and''' (a[n] != 0)&lt;br /&gt;
       a[n] = 0&lt;br /&gt;
       n--&lt;br /&gt;
   '''if''' n == -1&lt;br /&gt;
     '''return''' ''null''&lt;br /&gt;
   a[n] = 1&lt;br /&gt;
   '''return''' a&lt;br /&gt;
Приведённый алгоритм эквивалентен прибавлению единицы к битовому вектору. &lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|0||1||0||1||style=&amp;quot;background:#FFCC00&amp;quot;|1||исходный битовый вектор&lt;br /&gt;
|-&lt;br /&gt;
| || || || ||^|| начинаем идти с конца&lt;br /&gt;
|-&lt;br /&gt;
|0||1||0||style=&amp;quot;background:#FFCC00&amp;quot;|0||style=&amp;quot;background:#FFCC00&amp;quot;|0|| пока элементы равны 1, заменяем их на 0&lt;br /&gt;
|-&lt;br /&gt;
|0||1||style=&amp;quot;background:#FFCC00&amp;quot;|1||0||0|| меняем первый не удовлетворяющий условию цикла элемент на 1&lt;br /&gt;
|-&lt;br /&gt;
|'''0'''||'''1'''||'''1'''||'''0'''||'''0'''||следующий битовый вектор&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующей перестановки ==&lt;br /&gt;
* Двигаясь справа налево, находим элемент, нарушающий убывающую последовательность (в обычном порядке, слева направо, см. пример)&lt;br /&gt;
* Меняем его с минимальным элементом, большим нашего, стоящим правее&lt;br /&gt;
* Перевернем правую часть&lt;br /&gt;
&lt;br /&gt;
 '''int[]''' nextPermutation('''int[]''' a): &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} длина перестановки&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''for''' i = n - 2 '''downto''' 0&lt;br /&gt;
     '''if''' a[i] &amp;lt; a[i + 1]&lt;br /&gt;
       min = i + 1;&lt;br /&gt;
       '''for''' j = i + 1 '''to''' n - 1&lt;br /&gt;
         '''if''' (a[j] &amp;lt; a[min]) '''and''' (a[j] &amp;gt; a[i])&lt;br /&gt;
           min = j&lt;br /&gt;
       swap(a[i], a[min])&lt;br /&gt;
       reverse(a, i + 1, n - 1)&lt;br /&gt;
       '''return''' a&lt;br /&gt;
   '''return''' ''null'' &lt;br /&gt;
&lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||3||style=&amp;quot;background:#FFCC00&amp;quot;|2||5||style=&amp;quot;background:#FFCC00&amp;quot;|4||исходная перестановка&lt;br /&gt;
|-&lt;br /&gt;
| || ||^|| || ||находим элемент, нарушающий убывающую последовательность&lt;br /&gt;
|-&lt;br /&gt;
| || || || ||^||минимальный элемент больше нашего&lt;br /&gt;
|-&lt;br /&gt;
|1||3||style=&amp;quot;background:#FFCC00&amp;quot;|4||5||style=&amp;quot;background:#FFCC00&amp;quot;|2||меняем их местами&lt;br /&gt;
|-&lt;br /&gt;
|1||3||4||style=&amp;quot;background:#FFCC00&amp;quot;|2||style=&amp;quot;background:#FFCC00&amp;quot;|5||разворачивам правую часть&lt;br /&gt;
|-&lt;br /&gt;
|'''1'''||'''3'''||'''4'''||'''2'''||'''5'''||следующая перестановка&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующей мультиперестановки ==&lt;br /&gt;
* Двигаясь справа налево, находим элемент, нарушающий убывающую последовательность (в обычном порядке, слева направо, см. пример).&lt;br /&gt;
* Меняем его с минимальным элементом, большим нашего, стоящим правее.&lt;br /&gt;
* Переворачиваем правую часть.&lt;br /&gt;
 '''int[]''' nextMultiperm('''int[]''' b):  &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} длина мультиперестановки&amp;lt;/font&amp;gt;&lt;br /&gt;
     i = n - 2&lt;br /&gt;
     '''while''' (i &amp;gt;= 0) '''and''' (b[i] &amp;gt;= b[i + 1]) &lt;br /&gt;
       i--&lt;br /&gt;
     '''if''' i &amp;gt;= 0 &lt;br /&gt;
       j = i + 1&lt;br /&gt;
       '''while''' (j &amp;lt; n - 1) '''and''' (b[j + 1] &amp;gt; b[i]) &lt;br /&gt;
         j++&lt;br /&gt;
       swap(b[i] , b[j])&lt;br /&gt;
       reverse(b, i + 1, n - 1)&lt;br /&gt;
       '''return''' b&lt;br /&gt;
     '''else'''&lt;br /&gt;
       '''return''' ''null''&lt;br /&gt;
&lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||1||style=&amp;quot;background:#FFCC00&amp;quot;|2||style=&amp;quot;background:#FFCC00&amp;quot;|3||Исходная перестановка.&lt;br /&gt;
|-&lt;br /&gt;
| || || || ||^|| ||Находим элемент, нарушающий убывающую последовательность.&lt;br /&gt;
|-&lt;br /&gt;
| || || || || ||^||Минимальный элемент больше нашего.&lt;br /&gt;
|-&lt;br /&gt;
|1||2||3||1||style=&amp;quot;background:#FFCC00&amp;quot;|3||style=&amp;quot;background:#FFCC00&amp;quot;|2||Меняем их местами.&lt;br /&gt;
|-&lt;br /&gt;
|'''1'''||'''2'''||'''3'''||'''1'''||'''3'''||'''2'''||Следующая мультиперестановка.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующего сочетания ==&lt;br /&gt;
&lt;br /&gt;
* Добавим в конец массива с сочетанием &amp;lt;tex&amp;gt;N+1&amp;lt;/tex&amp;gt; – максимальный элемент.&lt;br /&gt;
* Пойдём справа налево. Будем искать номер элемента, который отличается от предыдущего на &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; и больше.&lt;br /&gt;
* Увеличим найденный элемент на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, и допишем в конец минимально возможный хвост, если такого элемента нет – на вход было дано последнее сочетание.&lt;br /&gt;
 '''int[]''' nextChoose('''int[]''' a, '''int''' n, '''int''' k): &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;n,k &amp;lt;/tex&amp;gt; {{---}} параметры сочетания&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''for''' i = 0 '''to''' k - 1 &lt;br /&gt;
     b[i] = a[i]&lt;br /&gt;
   b[k] = n + 1&lt;br /&gt;
   i = k - 1&lt;br /&gt;
   '''while''' (i &amp;gt;= 0) '''and''' (b[i + 1] - b[i] &amp;lt; 2) &lt;br /&gt;
     i--&lt;br /&gt;
   '''if''' i &amp;gt;= 0 &lt;br /&gt;
      b[i]++&lt;br /&gt;
      '''for''' j = i + 1 '''to''' k - 1 &lt;br /&gt;
        b[j] = b[j - 1] + 1&lt;br /&gt;
      '''for''' i = 0 '''to''' k - 1 &lt;br /&gt;
        a[i] = b[i]&lt;br /&gt;
      '''return''' a&lt;br /&gt;
   '''else'''&lt;br /&gt;
     '''return''' ''null''&lt;br /&gt;
&lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||5||6||style=&amp;quot;background:#FFCC00&amp;quot;|'''7'''||Дописываем 7 в конец сочетания.&lt;br /&gt;
|-&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|2||5||6||'''7'''||&lt;br /&gt;
|-&lt;br /&gt;
| ||^|| || || ||Находим элемент i, a[i + 1] - a[ i ] &amp;gt;= 2&lt;br /&gt;
|-&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|3||5||6||'''7'''||Увеличиваем его на 1.&lt;br /&gt;
|-&lt;br /&gt;
|1||3||style=&amp;quot;background:#FFCC00&amp;quot;|4||style=&amp;quot;background:#FFCC00&amp;quot;|5||style=&amp;quot;background:#FFCC00&amp;quot;|'''6'''||Дописываем минимальный хвост.&lt;br /&gt;
|-&lt;br /&gt;
|'''1'''||'''3'''||'''4'''||'''5'''||''' '''||Следующее сочетание.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующего разбиения на слагаемые ==&lt;br /&gt;
Рассматриваемый алгоритм находит следующее [[комбинаторные объекты|разбиение на слагаемые]], при этом разбиение упорядоченно по возрастанию.&lt;br /&gt;
* Увеличим предпоследнее слагаемое на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, уменьшим последнее слагаемое на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
** Если предпоследнее слагаемое стало больше последнего, то увеличиваем предпоследнее слагаемое на величину последнего.&lt;br /&gt;
** Если предпоследнее слагаемое умноженное на 2 меньше последнего, то разбиваем последнее слагаемое &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; на два слагаемых &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; таких, что &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; равно предпоследнему слагаемому, а &amp;lt;tex&amp;gt;b = s - a&amp;lt;/tex&amp;gt;. Повторяем этот процесс, пока разбиение остается корректным, то есть предпоследнее слагаемое хотя бы в два раза меньше последнего.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; {{---}} список, содержащий разбиение данного числа &amp;lt;tex&amp;gt;b.size&amp;lt;/tex&amp;gt;{{---}} его размер &amp;lt;/font&amp;gt;&lt;br /&gt;
 '''list&amp;lt;int&amp;gt;'''  nextPartition('''list&amp;lt;int&amp;gt;''' b): &lt;br /&gt;
    b[b.size - 1]--&lt;br /&gt;
    b[b.size - 2]++&lt;br /&gt;
    '''if''' b[b.size - 2] &amp;gt; b[b.size - 1] &lt;br /&gt;
       b[b.size - 2] += b[b.size - 1]&lt;br /&gt;
       b.remove(b.size - 1)&lt;br /&gt;
    '''else'''&lt;br /&gt;
      '''while''' b[b.size - 2] * 2 &amp;lt;= b[b.size - 1] &lt;br /&gt;
        b.add(b[b.size - 1] - b[b.size - 2])&lt;br /&gt;
        b[b.size - 2] = b[b.size - 3]&lt;br /&gt;
    '''return''' b&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|1||style=&amp;quot;background:#FFCC00&amp;quot;|7|| || ||Прибавим 1 + 1, вычтем 7 - 1.&lt;br /&gt;
|-&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|2||style=&amp;quot;background:#FFCC00&amp;quot;|6|| || ||Проверяем: 2 &amp;lt; 6, значит разбиваем 6 пока оно не станет меньше 4&lt;br /&gt;
|-&lt;br /&gt;
|1||2||style=&amp;quot;background:#FFCC00&amp;quot;|2||style=&amp;quot;background:#FFCC00&amp;quot;|4|| ||&lt;br /&gt;
|-&lt;br /&gt;
|1||2||2||style=&amp;quot;background:#FFCC00&amp;quot;|2||style=&amp;quot;background:#FFCC00&amp;quot;|2||&lt;br /&gt;
|-&lt;br /&gt;
|'''1'''||'''2'''||'''2'''||'''2'''||'''2'''||Следующее разбиение на слагаемые числа 9.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|4||style=&amp;quot;background:#FFCC00&amp;quot;|5||Прибавим 4 + 1, вычтем 5 - 1.&lt;br /&gt;
|-&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|5||style=&amp;quot;background:#FFCC00&amp;quot;|4||Проверяем: 5 &amp;gt; 4, значит прибавим к 5 + 4.&lt;br /&gt;
|-&lt;br /&gt;
|1||9||style=&amp;quot;background:#FFCC00&amp;quot;|4||Удалим последний элемент.&lt;br /&gt;
|-&lt;br /&gt;
|'''1'''||'''9'''||||Следующее разбиение на слагаемые числа 10.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующего разбиения на подмножества ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим множество первых n натуральных чисел:&amp;lt;tex&amp;gt;N_n = \{1, 2, ..., n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Упорядочим все разбиения на множества &amp;lt;tex&amp;gt;N_n&amp;lt;/tex&amp;gt; лексикографически. Для этого, во-первых, в каждом разбиении упорядочим множества лексикографически. Будем говорить, что подмножество &amp;lt;tex&amp;gt; A \subset N_n &amp;lt;/tex&amp;gt; лексикографически меньше подмножества &amp;lt;tex&amp;gt; B \subset N_n &amp;lt;/tex&amp;gt; , если верно одно из следующих условий:&lt;br /&gt;
&lt;br /&gt;
*существует &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; такое, что &amp;lt;tex&amp;gt;i \in A&amp;lt;/tex&amp;gt; , &amp;lt;tex&amp;gt;i \notin B&amp;lt;/tex&amp;gt;, для всех &amp;lt;tex&amp;gt;j &amp;lt; i: j \in A&amp;lt;/tex&amp;gt; если и только если &amp;lt;tex&amp;gt;j \in B&amp;lt;/tex&amp;gt; , и существует &amp;lt;tex&amp;gt;k &amp;gt; i&amp;lt;/tex&amp;gt; такое что &amp;lt;tex&amp;gt;k \in B&amp;lt;/tex&amp;gt;;&lt;br /&gt;
* &amp;lt;tex&amp;gt; A \subset B &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;i &amp;lt; j&amp;lt;/tex&amp;gt; для всех &amp;lt;tex&amp;gt;i \in A&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j \in B&amp;lt;/tex&amp;gt; \ &amp;lt;tex&amp;gt; A &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Разбиения упорядочены лексикографически следующим образом. Разбиение &amp;lt;tex&amp;gt;N_n = A_1 \cup A_2 \cup . . . \cup A_k&amp;lt;/tex&amp;gt; лексикографически меньше разбиения &amp;lt;tex&amp;gt;N_n = B_1 \cup B_2 \cup . . . \cup B_l&amp;lt;/tex&amp;gt; если существует такое &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, что &amp;lt;tex&amp;gt;A_1 = B_1, A_2 = B_2, . . . ,A_{i - 1} = B_{i - 1}, A_i &amp;lt; B_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Рассмотрим алгоритм нахождения лексикографически следующего разбиения на подмножества:'''&lt;br /&gt;
*Будем хранить подмножества в списке списков, например, разбиение &amp;lt;tex&amp;gt; \{1, 2, 3\} ~ \{4, 5\}&amp;lt;/tex&amp;gt; будет выглядеть так:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3&lt;br /&gt;
|-&lt;br /&gt;
|4||5|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* Будем поддерживать массив удалённых элементов {{---}} элементы, которые затем нужно будет вернуть в разбиение.&lt;br /&gt;
&lt;br /&gt;
* Двигаясь снизу вверх будем рассматривать подмножества.&lt;br /&gt;
** Если мы можем дописать в текущее подмножество минимальный элемент из удалённых, то мы нашли следующее разбиение и нужно завершить цикл.&lt;br /&gt;
** Если дописать не можем, значит, либо нужно укоротить и заменить какой-то элемент в текущем подмножестве, либо перейти к следующему подмножеству. Будем идти справа налево и рассматривать элементы:&lt;br /&gt;
*** Если мы можем заменить текущий элемент минимальным удалённым {{---}} мы нашли следующее разбиение, завершаем оба цикла и выполняем алгоритм дальше. Стоит отметить, что нельзя перезаписывать последний элемент в подмножестве, иначе мы не сможем дописать минимальный хвост после этого подмножества {{---}} в удалённых будет элемент меньше текущего и мы не сможем выписать удаленные элементы так, чтобы получилось корректное разбиение.&lt;br /&gt;
*** Если заменить текущий элемент каким-то из удалённых нельзя, то следует удалить и этот.&lt;br /&gt;
* Допишем лексикографически минимальный хвост подмножеств из оставшихся удалённых элементов.&lt;br /&gt;
&lt;br /&gt;
 '''list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;''' nextSetPartition('''list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;''' a):&lt;br /&gt;
   used = '''list&amp;lt;int&amp;gt;'''&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// a {{---}} список, содержащий подмножества&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// used {{---}} список, в котором мы храним удаленные элементы&amp;lt;/font&amp;gt;&lt;br /&gt;
   fl = ''false''&lt;br /&gt;
   '''for''' i = a.size - 1 '''downto''' 0&lt;br /&gt;
     '''if''' (used.size != 0) '''and''' (max(used) &amp;gt; a[i][-1])   &amp;lt;font color=green&amp;gt;// в удалённых есть хотя бы один элемент, который мы можем добавить в конец.&amp;lt;/font&amp;gt;&lt;br /&gt;
       m = '''минимум из''' used '''строго больше''' a[i][-1]&lt;br /&gt;
       a[i].add(m)   &amp;lt;font color=green&amp;gt;//добавляем&amp;lt;/font&amp;gt;&lt;br /&gt;
       used.remove(m)&lt;br /&gt;
       '''break'''&lt;br /&gt;
     '''for''' j = a[i].size - 1 '''downto''' 0&lt;br /&gt;
       '''if''' (used.size != 0) '''and''' (j != 0) '''and''' (max(used) &amp;gt; a[i][j])   &amp;lt;font color=green&amp;gt;//если можем заменить элемент, другим элементом из списка used и он не последний&amp;lt;/font&amp;gt;&lt;br /&gt;
         m = '''минимум из''' used '''строго больше''' a[i][j]&lt;br /&gt;
         old = a[i][j]&lt;br /&gt;
         a[i][j] = m   &amp;lt;font color=green&amp;gt;//заменяем&amp;lt;/font&amp;gt;&lt;br /&gt;
         used.remove(m)&lt;br /&gt;
         used.add(old)&lt;br /&gt;
         fl = ''true''&lt;br /&gt;
         '''break'''&lt;br /&gt;
       '''else'''&lt;br /&gt;
         used.add(a[i][-1])&lt;br /&gt;
         a[i].pop()&lt;br /&gt;
         '''if''' a[i].size == 0&lt;br /&gt;
           a.pop()&lt;br /&gt;
      '''if''' fl &lt;br /&gt;
        '''break'''&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;//далее выведем все удалённые, которые не выбрали&amp;lt;/font&amp;gt;&lt;br /&gt;
   sort(used)&lt;br /&gt;
   '''for''' i = 0 '''to''' used.size - 1&lt;br /&gt;
      a.add('''list&amp;lt;int&amp;gt;'''(used[i]))   &amp;lt;font color=green&amp;gt;//добавляем лексикографически минимальных хвост&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''return''' a&lt;br /&gt;
&lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
&lt;br /&gt;
'''Рассмотрим следующее разбиение:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3&lt;br /&gt;
|-&lt;br /&gt;
|4||5|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''1 Шаг:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||&lt;br /&gt;
|-&lt;br /&gt;
|4||style=&amp;quot;background:#FFCC00&amp;quot;|5||||&lt;br /&gt;
|-&lt;br /&gt;
| ||^|| ||Удалили элемент 5.&lt;br /&gt;
|-&lt;br /&gt;
| || || ||Удалённые элементы&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2 Шаг:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#FFCC00&amp;quot;|4|| ||||&lt;br /&gt;
|-&lt;br /&gt;
|^|| || ||Удалили элемент 4. Так как он является последним в подмножестве, то мы не можем заменить его на другой.&lt;br /&gt;
|-&lt;br /&gt;
|5|| || ||Удалённые элементы&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''3 Шаг:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||style=&amp;quot;background:#FFCC00&amp;quot;|4||&lt;br /&gt;
|-&lt;br /&gt;
| || || ||^||Дополнили первое подмножество элементом 4&lt;br /&gt;
|-&lt;br /&gt;
|5|| || || ||Удалённые элементы&lt;br /&gt;
|}  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''4 Шаг:''' &lt;br /&gt;
    &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||4||&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#FFCC00&amp;quot;|5|| || || ||Дописали лексикографически минимальный хвост&lt;br /&gt;
|-&lt;br /&gt;
| || || || ||Удалённые элементы&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== См.также ==&lt;br /&gt;
* [[Получение предыдущего объекта]]&lt;br /&gt;
* [[Получение объекта по номеру]]&lt;br /&gt;
* [[Получение номера по объекту]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
&lt;br /&gt;
* [http://rain.ifmo.ru/cat/view.php/vis/combinations/permutations-2000 Визуализатор перестановок]&lt;br /&gt;
* [http://cppalgo.blogspot.com/2011/02/episode-2.html Пример компактного кода для перестановок (С++)]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Комбинаторика]]&lt;/div&gt;</summary>
		<author><name>Irdkwmnsb</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D1%81%D0%BB%D0%B5%D0%B4%D1%83%D1%8E%D1%89%D0%B5%D0%B3%D0%BE_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%B0&amp;diff=77068</id>
		<title>Получение следующего объекта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D1%81%D0%BB%D0%B5%D0%B4%D1%83%D1%8E%D1%89%D0%B5%D0%B3%D0%BE_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%B0&amp;diff=77068"/>
				<updated>2021-01-09T16:56:42Z</updated>
		
		<summary type="html">&lt;p&gt;Irdkwmnsb: Исправление замены&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Алгоритм ==&lt;br /&gt;
{{Определение|definition= '''Получение следующего объекта''' {{---}} это нахождение объекта, следующего за данным в [[Лексикографический порядок|лексикографическом порядке]].&lt;br /&gt;
}}&lt;br /&gt;
Объект &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; называется следующим за &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;P &amp;lt; Q&amp;lt;/tex&amp;gt; и не найдется такого &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt;, что &amp;lt;tex&amp;gt;P &amp;lt; R &amp;lt; Q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Отсюда понятен алгоритм:&lt;br /&gt;
* находим суффикс минимальной длины, который можно изменить без изменения префикса текущего объекта &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* к оставшейся части дописываем минимальный возможный элемент (чтобы было выполнено правило &amp;lt;tex&amp;gt;P &amp;lt; Q&amp;lt;/tex&amp;gt;),&lt;br /&gt;
* дописываем минимальный возможный хвост.&lt;br /&gt;
По построению получаем, что &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; {{---}} минимально возможный.&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующего битового вектора ==&lt;br /&gt;
* Находим минимальный суффикс, в котором есть &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, его можно увеличить, не меняя оставшейся части&lt;br /&gt;
* Вместо &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; записываем &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; &lt;br /&gt;
* Дописываем минимально возможный хвост из нулей&lt;br /&gt;
 '''int[]''' nextVector('''int[]''' a): &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} длина вектора&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''while''' (n &amp;gt;= 0) '''and''' (a[n] != 0)&lt;br /&gt;
       a[n] = 0&lt;br /&gt;
       n--&lt;br /&gt;
   '''if''' n == -1&lt;br /&gt;
     '''return''' ''null''&lt;br /&gt;
   a[n] = 1&lt;br /&gt;
   '''return''' a&lt;br /&gt;
Приведённый алгоритм эквивалентен прибавлению единицы к битовому вектору. &lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|0||1||0||1||style=&amp;quot;background:#FFCC00&amp;quot;|1||исходный битовый вектор&lt;br /&gt;
|-&lt;br /&gt;
| || || || ||^|| начинаем идти с конца&lt;br /&gt;
|-&lt;br /&gt;
|0||1||0||style=&amp;quot;background:#FFCC00&amp;quot;|0||style=&amp;quot;background:#FFCC00&amp;quot;|0|| пока элементы равны 1, заменяем их на 0&lt;br /&gt;
|-&lt;br /&gt;
|0||1||style=&amp;quot;background:#FFCC00&amp;quot;|1||0||0|| меняем первый не удовлетворяющий условию цикла элемент на 1&lt;br /&gt;
|-&lt;br /&gt;
|'''0'''||'''1'''||'''1'''||'''0'''||'''0'''||следующий битовый вектор&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующей перестановки ==&lt;br /&gt;
* Двигаясь справа налево, находим элемент, нарушающий убывающую последовательность (в обычном порядке, слева направо, см. пример)&lt;br /&gt;
* Меняем его с минимальным элементом, большим нашего, стоящим правее&lt;br /&gt;
* Перевернем правую часть&lt;br /&gt;
&lt;br /&gt;
 '''int[]''' nextPermutation('''int[]''' a): &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} длина перестановки&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''for''' i = n - 2 '''downto''' 0&lt;br /&gt;
     '''if''' a[i] &amp;lt; a[i + 1]&lt;br /&gt;
       min = i + 1;&lt;br /&gt;
       '''for''' j = i + 1 '''to''' n - 1&lt;br /&gt;
         '''if''' (a[j] &amp;lt; a[min]) '''and''' (a[j] &amp;gt; a[i])&lt;br /&gt;
           min = j&lt;br /&gt;
       swap(a[i], a[min])&lt;br /&gt;
       reverse(a, i + 1, n - 1)&lt;br /&gt;
       '''return''' a&lt;br /&gt;
   '''return''' ''null'' &lt;br /&gt;
&lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||3||style=&amp;quot;background:#FFCC00&amp;quot;|2||5||style=&amp;quot;background:#FFCC00&amp;quot;|4||исходная перестановка&lt;br /&gt;
|-&lt;br /&gt;
| || ||^|| || ||находим элемент, нарушающий убывающую последовательность&lt;br /&gt;
|-&lt;br /&gt;
| || || || ||^||минимальный элемент больше нашего&lt;br /&gt;
|-&lt;br /&gt;
|1||3||style=&amp;quot;background:#FFCC00&amp;quot;|4||5||style=&amp;quot;background:#FFCC00&amp;quot;|2||меняем их местами&lt;br /&gt;
|-&lt;br /&gt;
|1||3||4||style=&amp;quot;background:#FFCC00&amp;quot;|2||style=&amp;quot;background:#FFCC00&amp;quot;|5||разворачивам правую часть&lt;br /&gt;
|-&lt;br /&gt;
|'''1'''||'''3'''||'''4'''||'''2'''||'''5'''||следующая перестановка&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующей мультиперестановки ==&lt;br /&gt;
* Двигаясь справа налево, находим элемент, нарушающий убывающую последовательность (в обычном порядке, слева направо, см. пример).&lt;br /&gt;
* Меняем его с минимальным элементом, большим нашего, стоящим правее.&lt;br /&gt;
* Переворачиваем правую часть.&lt;br /&gt;
 '''int[]''' nextMultiperm('''int[]''' b):  &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} длина мультиперестановки&amp;lt;/font&amp;gt;&lt;br /&gt;
     i = n - 2&lt;br /&gt;
     '''while''' (i &amp;gt;= 0) '''and''' (b[i] &amp;gt;= b[i + 1]) &lt;br /&gt;
       i--&lt;br /&gt;
     '''if''' i &amp;gt;= 0 &lt;br /&gt;
       j = i + 1&lt;br /&gt;
       '''while''' (j &amp;lt; n - 1) '''and''' (b[j + 1] &amp;gt; b[i]) &lt;br /&gt;
         j++&lt;br /&gt;
       swap(b[i] , b[j])&lt;br /&gt;
       reverse(b, i + 1, n - 1)&lt;br /&gt;
       '''return''' b&lt;br /&gt;
     '''else'''&lt;br /&gt;
       '''return''' ''null''&lt;br /&gt;
&lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||1||style=&amp;quot;background:#FFCC00&amp;quot;|2||style=&amp;quot;background:#FFCC00&amp;quot;|3||Исходная перестановка.&lt;br /&gt;
|-&lt;br /&gt;
| || || || ||^|| ||Находим элемент, нарушающий убывающую последовательность.&lt;br /&gt;
|-&lt;br /&gt;
| || || || || ||^||Минимальный элемент больше нашего.&lt;br /&gt;
|-&lt;br /&gt;
|1||2||3||1||style=&amp;quot;background:#FFCC00&amp;quot;|3||style=&amp;quot;background:#FFCC00&amp;quot;|2||Меняем их местами.&lt;br /&gt;
|-&lt;br /&gt;
|'''1'''||'''2'''||'''3'''||'''1'''||'''3'''||'''2'''||Следующая мультиперестановка.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующего сочетания ==&lt;br /&gt;
&lt;br /&gt;
* Добавим в конец массива с сочетанием &amp;lt;tex&amp;gt;N+1&amp;lt;/tex&amp;gt; – максимальный элемент.&lt;br /&gt;
* Пойдём справа налево. Будем искать номер элемента, который отличается от предыдущего на &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; и больше.&lt;br /&gt;
* Увеличим найденный элемент на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, и допишем в конец минимально возможный хвост, если такого элемента нет – на вход было дано последнее сочетание.&lt;br /&gt;
 '''int[]''' nextChoose('''int[]''' a, '''int''' n, '''int''' k): &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;n,k &amp;lt;/tex&amp;gt; {{---}} параметры сочетания&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''for''' i = 0 '''to''' k - 1 &lt;br /&gt;
     b[i] = a[i]&lt;br /&gt;
   b[k] = n + 1&lt;br /&gt;
   i = k - 1&lt;br /&gt;
   '''while''' (i &amp;gt;= 0) '''and''' (b[i + 1] - b[i] &amp;lt; 2) &lt;br /&gt;
     i--&lt;br /&gt;
   '''if''' i &amp;gt;= 0 &lt;br /&gt;
      b[i]++&lt;br /&gt;
      '''for''' j = i + 1 '''to''' k - 1 &lt;br /&gt;
        b[j] = b[j - 1] + 1&lt;br /&gt;
      '''for''' i = 0 '''to''' k - 1 &lt;br /&gt;
        a[i] = b[i]&lt;br /&gt;
      '''return''' a&lt;br /&gt;
   '''else'''&lt;br /&gt;
     '''return''' ''null''&lt;br /&gt;
&lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||5||6||style=&amp;quot;background:#FFCC00&amp;quot;|'''7'''||Дописываем 7 в конец сочетания.&lt;br /&gt;
|-&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|2||5||6||'''7'''||&lt;br /&gt;
|-&lt;br /&gt;
| ||^|| || || ||Находим элемент i, a[i + 1] - a[ i ] &amp;gt;= 2&lt;br /&gt;
|-&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|3||5||6||'''7'''||Увеличиваем его на 1.&lt;br /&gt;
|-&lt;br /&gt;
|1||3||style=&amp;quot;background:#FFCC00&amp;quot;|4||style=&amp;quot;background:#FFCC00&amp;quot;|5||style=&amp;quot;background:#FFCC00&amp;quot;|'''6'''||Дописываем минимальный хвост.&lt;br /&gt;
|-&lt;br /&gt;
|'''1'''||'''3'''||'''4'''||'''5'''||''' '''||Следующее сочетание.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующего разбиения на слагаемые ==&lt;br /&gt;
Рассматриваемый алгоритм находит следующее [[комбинаторные объекты|разбиение на слагаемые]], при этом разбиение упорядоченно по возрастанию.&lt;br /&gt;
* Увеличим предпоследнее слагаемое на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, уменьшим последнее слагаемое на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
** Если предпоследнее слагаемое стало больше последнего, то увеличиваем предпоследнее слагаемое на величину последнего.&lt;br /&gt;
** Если предпоследнее слагаемое умноженное на 2 меньше последнего, то разбиваем последнее слагаемое &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; на два слагаемых &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; таких, что &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; равно предпоследнему слагаемому, а &amp;lt;tex&amp;gt;b = s - a&amp;lt;/tex&amp;gt;. Повторяем этот процесс, пока разбиение остается корректным, то есть предпоследнее слагаемое хотя бы в два раза меньше последнего.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; {{---}} список, содержащий разбиение данного числа &amp;lt;tex&amp;gt;b.size&amp;lt;/tex&amp;gt;{{---}} его размер &amp;lt;/font&amp;gt;&lt;br /&gt;
 '''list&amp;lt;int&amp;gt;'''  nextPartition('''list&amp;lt;int&amp;gt;''' b): &lt;br /&gt;
    b[b.size - 1]--&lt;br /&gt;
    b[b.size - 2]++&lt;br /&gt;
    '''if''' b[b.size - 2] &amp;gt; b[b.size - 1] &lt;br /&gt;
       b[b.size - 2] += b[b.size - 1]&lt;br /&gt;
       b.remove(b.size - 1)&lt;br /&gt;
    '''else'''&lt;br /&gt;
      '''while''' b[b.size - 2] * 2 &amp;lt;= b[b.size - 1] &lt;br /&gt;
        b.add(b[b.size - 1] - b[b.size - 2])&lt;br /&gt;
        b[b.size - 2] = b[b.size - 3]&lt;br /&gt;
    '''return''' b&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|1||style=&amp;quot;background:#FFCC00&amp;quot;|7|| || ||Прибавим 1 + 1, вычтем 7 - 1.&lt;br /&gt;
|-&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|2||style=&amp;quot;background:#FFCC00&amp;quot;|6|| || ||Проверяем: 2 &amp;lt; 6, значит разбиваем 6 пока оно не станет меньше 4&lt;br /&gt;
|-&lt;br /&gt;
|1||2||style=&amp;quot;background:#FFCC00&amp;quot;|2||style=&amp;quot;background:#FFCC00&amp;quot;|4|| ||&lt;br /&gt;
|-&lt;br /&gt;
|1||2||2||style=&amp;quot;background:#FFCC00&amp;quot;|2||style=&amp;quot;background:#FFCC00&amp;quot;|2||&lt;br /&gt;
|-&lt;br /&gt;
|'''1'''||'''2'''||'''2'''||'''2'''||'''2'''||Следующее разбиение на слагаемые числа 9.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|4||style=&amp;quot;background:#FFCC00&amp;quot;|5||Прибавим 4 + 1, вычтем 5 - 1.&lt;br /&gt;
|-&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|5||style=&amp;quot;background:#FFCC00&amp;quot;|4||Проверяем: 5 &amp;gt; 4, значит прибавим к 5 + 4.&lt;br /&gt;
|-&lt;br /&gt;
|1||9||style=&amp;quot;background:#FFCC00&amp;quot;|4||Удалим последний элемент.&lt;br /&gt;
|-&lt;br /&gt;
|'''1'''||'''9'''||||Следующее разбиение на слагаемые числа 10.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующего разбиения на подмножества ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим множество первых n натуральных чисел:&amp;lt;tex&amp;gt;N_n = \{1, 2, ..., n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Упорядочим все разбиения на множества &amp;lt;tex&amp;gt;N_n&amp;lt;/tex&amp;gt; лексикографически. Для этого, во-первых, в каждом разбиении упорядочим множества лексикографически. Будем говорить, что подмножество &amp;lt;tex&amp;gt; A \subset N_n &amp;lt;/tex&amp;gt; лексикографически меньше подмножества &amp;lt;tex&amp;gt; B \subset N_n &amp;lt;/tex&amp;gt; , если верно одно из следующих условий:&lt;br /&gt;
&lt;br /&gt;
*существует &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; такое, что &amp;lt;tex&amp;gt;i \in A&amp;lt;/tex&amp;gt; , &amp;lt;tex&amp;gt;i \notin B&amp;lt;/tex&amp;gt;, для всех &amp;lt;tex&amp;gt;j &amp;lt; i: j \in A&amp;lt;/tex&amp;gt; если и только если &amp;lt;tex&amp;gt;j \in B&amp;lt;/tex&amp;gt; , и существует &amp;lt;tex&amp;gt;k &amp;gt; i&amp;lt;/tex&amp;gt; такое что &amp;lt;tex&amp;gt;k \in B&amp;lt;/tex&amp;gt;;&lt;br /&gt;
* &amp;lt;tex&amp;gt; A \subset B &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;i &amp;lt; j&amp;lt;/tex&amp;gt; для всех &amp;lt;tex&amp;gt;i \in A&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j \in B&amp;lt;/tex&amp;gt; \ &amp;lt;tex&amp;gt; A &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Разбиения упорядочены лексикографически следующим образом. Разбиение &amp;lt;tex&amp;gt;N_n = A_1 \cup A_2 \cup . . . \cup A_k&amp;lt;/tex&amp;gt; лексикографически меньше разбиения &amp;lt;tex&amp;gt;N_n = B_1 \cup B_2 \cup . . . \cup B_l&amp;lt;/tex&amp;gt; если существует такое &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, что &amp;lt;tex&amp;gt;A_1 = B_1, A_2 = B_2, . . . ,A_{i - 1} = B_{i - 1}, A_i &amp;lt; B_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Рассмотрим алгоритм нахождения лексикографически следующего разбиения на подмножества:'''&lt;br /&gt;
*Будем хранить подмножества в списке списков, например, разбиение &amp;lt;tex&amp;gt; \{1, 2, 3\} ~ \{4, 5\}&amp;lt;/tex&amp;gt; будет выглядеть так:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3&lt;br /&gt;
|-&lt;br /&gt;
|4||5|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* Будем поддерживать массив удалённых элементов {{---}} элементы, которые затем нужно будет вернуть в разбиение.&lt;br /&gt;
&lt;br /&gt;
* Двигаясь снизу вверх будем рассматривать подмножества.&lt;br /&gt;
** Если мы можем дописать в текущее подмножество минимальный элемент из удалённых, то мы нашли следующее разбиение и нужно завершить цикл.&lt;br /&gt;
** Если дописать не можем, значит, либо нужно укоротить и заменить какой-то элемент в текущем подмножестве, либо перейти к следующему подмножеству. Будем идти справа налево и рассматривать элементы:&lt;br /&gt;
*** Если мы можем заменить текущий элемент минимальным удалённым {{---}} мы нашли следующее разбиение, завершаем оба цикла и выполняем алгоритм дальше. Стоит отметить, что нельзя перезаписывать последний элемент в подмножестве, иначе мы не сможем дописать минимальный хвост после этого подмножества {{---}} в удалённых будет элемент меньше текущего и мы не сможем выписать удаленные элементы так, чтобы получилось корректное разбиение.&lt;br /&gt;
*** Если заменить текущий элемент каким-то из удалённых нельзя, то следует удалить и этот.&lt;br /&gt;
* Допишем лексикографически минимальный хвост подмножеств из оставшихся удалённых элементов.&lt;br /&gt;
&lt;br /&gt;
 '''list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;''' nextSetPartition('''list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;''' a):&lt;br /&gt;
   used = '''list&amp;lt;int&amp;gt;'''&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// a {{---}} список, содержащий подмножества&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// used {{---}} список, в котором мы храним удаленные элементы&amp;lt;/font&amp;gt;&lt;br /&gt;
   fl = ''false''&lt;br /&gt;
   '''for''' i = a.size - 1 '''downto''' 0&lt;br /&gt;
     '''if''' (used.size != 0) '''and''' (max(used) &amp;gt; a[i][-1])   &amp;lt;font color=green&amp;gt;// в удалённых есть хотя бы один элемент, который мы можем добавить в конец.&amp;lt;/font&amp;gt;&lt;br /&gt;
       m = '''минимум из''' used '''строго больше''' a[i][-1]&lt;br /&gt;
       a[i].add(m)   &amp;lt;font color=green&amp;gt;//добавляем&amp;lt;/font&amp;gt;&lt;br /&gt;
       used.remove(m)&lt;br /&gt;
       '''break'''&lt;br /&gt;
     '''for''' j = a[i].size - 1 '''downto''' 0&lt;br /&gt;
       '''if''' (used.size != 0) '''and''' (j != 0) '''and''' (max(used) &amp;gt; a[i][j])   &amp;lt;font color=green&amp;gt;//если можем заменить элемент, другим элементом из списка used и он не последний&amp;lt;/font&amp;gt;&lt;br /&gt;
         m = '''минимум из''' used '''строго больше''' a[i][-1]&lt;br /&gt;
         old = a[i][j]&lt;br /&gt;
         a[i][j] = m   &amp;lt;font color=green&amp;gt;//заменяем&amp;lt;/font&amp;gt;&lt;br /&gt;
         used.remove(m)&lt;br /&gt;
         used.add(old)&lt;br /&gt;
         fl = ''true''&lt;br /&gt;
         '''break'''&lt;br /&gt;
       '''else'''&lt;br /&gt;
         used.add(a[i][-1])&lt;br /&gt;
         a[i].pop()&lt;br /&gt;
         '''if''' a[i].size == 0&lt;br /&gt;
           a.pop()&lt;br /&gt;
      '''if''' fl &lt;br /&gt;
        '''break'''&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;//далее выведем все удалённые, которые не выбрали&amp;lt;/font&amp;gt;&lt;br /&gt;
   sort(used)&lt;br /&gt;
   '''for''' i = 0 '''to''' used.size - 1&lt;br /&gt;
      a.add('''list&amp;lt;int&amp;gt;'''(used[i]))   &amp;lt;font color=green&amp;gt;//добавляем лексикографически минимальных хвост&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''return''' a&lt;br /&gt;
&lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
&lt;br /&gt;
'''Рассмотрим следующее разбиение:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3&lt;br /&gt;
|-&lt;br /&gt;
|4||5|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''1 Шаг:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||&lt;br /&gt;
|-&lt;br /&gt;
|4||style=&amp;quot;background:#FFCC00&amp;quot;|5||||&lt;br /&gt;
|-&lt;br /&gt;
| ||^|| ||Удалили элемент 5.&lt;br /&gt;
|-&lt;br /&gt;
| || || ||Удалённые элементы&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2 Шаг:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#FFCC00&amp;quot;|4|| ||||&lt;br /&gt;
|-&lt;br /&gt;
|^|| || ||Удалили элемент 4. Так как он является последним в подмножестве, то мы не можем заменить его на другой.&lt;br /&gt;
|-&lt;br /&gt;
|5|| || ||Удалённые элементы&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''3 Шаг:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||style=&amp;quot;background:#FFCC00&amp;quot;|4||&lt;br /&gt;
|-&lt;br /&gt;
| || || ||^||Дополнили первое подмножество элементом 4&lt;br /&gt;
|-&lt;br /&gt;
|5|| || || ||Удалённые элементы&lt;br /&gt;
|}  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''4 Шаг:''' &lt;br /&gt;
    &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||4||&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#FFCC00&amp;quot;|5|| || || ||Дописали лексикографически минимальный хвост&lt;br /&gt;
|-&lt;br /&gt;
| || || || ||Удалённые элементы&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== См.также ==&lt;br /&gt;
* [[Получение предыдущего объекта]]&lt;br /&gt;
* [[Получение объекта по номеру]]&lt;br /&gt;
* [[Получение номера по объекту]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
&lt;br /&gt;
* [http://rain.ifmo.ru/cat/view.php/vis/combinations/permutations-2000 Визуализатор перестановок]&lt;br /&gt;
* [http://cppalgo.blogspot.com/2011/02/episode-2.html Пример компактного кода для перестановок (С++)]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Комбинаторика]]&lt;/div&gt;</summary>
		<author><name>Irdkwmnsb</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D1%81%D0%BB%D0%B5%D0%B4%D1%83%D1%8E%D1%89%D0%B5%D0%B3%D0%BE_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%B0&amp;diff=76785</id>
		<title>Получение следующего объекта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D1%81%D0%BB%D0%B5%D0%B4%D1%83%D1%8E%D1%89%D0%B5%D0%B3%D0%BE_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%B0&amp;diff=76785"/>
				<updated>2021-01-08T10:38:42Z</updated>
		
		<summary type="html">&lt;p&gt;Irdkwmnsb: Исправление алгоритма&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Алгоритм ==&lt;br /&gt;
{{Определение|definition= '''Получение следующего объекта''' {{---}} это нахождение объекта, следующего за данным в [[Лексикографический порядок|лексикографическом порядке]].&lt;br /&gt;
}}&lt;br /&gt;
Объект &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; называется следующим за &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;P &amp;lt; Q&amp;lt;/tex&amp;gt; и не найдется такого &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt;, что &amp;lt;tex&amp;gt;P &amp;lt; R &amp;lt; Q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Отсюда понятен алгоритм:&lt;br /&gt;
* находим суффикс минимальной длины, который можно изменить без изменения префикса текущего объекта &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* к оставшейся части дописываем минимальный возможный элемент (чтобы было выполнено правило &amp;lt;tex&amp;gt;P &amp;lt; Q&amp;lt;/tex&amp;gt;),&lt;br /&gt;
* дописываем минимальный возможный хвост.&lt;br /&gt;
По построению получаем, что &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; {{---}} минимально возможный.&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующего битового вектора ==&lt;br /&gt;
* Находим минимальный суффикс, в котором есть &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, его можно увеличить, не меняя оставшейся части&lt;br /&gt;
* Вместо &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; записываем &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; &lt;br /&gt;
* Дописываем минимально возможный хвост из нулей&lt;br /&gt;
 '''int[]''' nextVector('''int[]''' a): &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} длина вектора&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''while''' (n &amp;gt;= 0) '''and''' (a[n] != 0)&lt;br /&gt;
       a[n] = 0&lt;br /&gt;
       n--&lt;br /&gt;
   '''if''' n == -1&lt;br /&gt;
     '''return''' ''null''&lt;br /&gt;
   a[n] = 1&lt;br /&gt;
   '''return''' a&lt;br /&gt;
Приведённый алгоритм эквивалентен прибавлению единицы к битовому вектору. &lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|0||1||0||1||style=&amp;quot;background:#FFCC00&amp;quot;|1||исходный битовый вектор&lt;br /&gt;
|-&lt;br /&gt;
| || || || ||^|| начинаем идти с конца&lt;br /&gt;
|-&lt;br /&gt;
|0||1||0||style=&amp;quot;background:#FFCC00&amp;quot;|0||style=&amp;quot;background:#FFCC00&amp;quot;|0|| пока элементы равны 1, заменяем их на 0&lt;br /&gt;
|-&lt;br /&gt;
|0||1||style=&amp;quot;background:#FFCC00&amp;quot;|1||0||0|| меняем первый не удовлетворяющий условию цикла элемент на 1&lt;br /&gt;
|-&lt;br /&gt;
|'''0'''||'''1'''||'''1'''||'''0'''||'''0'''||следующий битовый вектор&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующей перестановки ==&lt;br /&gt;
* Двигаясь справа налево, находим элемент, нарушающий убывающую последовательность (в обычном порядке, слева направо, см. пример)&lt;br /&gt;
* Меняем его с минимальным элементом, большим нашего, стоящим правее&lt;br /&gt;
* Перевернем правую часть&lt;br /&gt;
&lt;br /&gt;
 '''int[]''' nextPermutation('''int[]''' a): &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} длина перестановки&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''for''' i = n - 2 '''downto''' 0&lt;br /&gt;
     '''if''' a[i] &amp;lt; a[i + 1]&lt;br /&gt;
       min = i + 1;&lt;br /&gt;
       '''for''' j = i + 1 '''to''' n - 1&lt;br /&gt;
         '''if''' (a[j] &amp;lt; a[min]) '''and''' (a[j] &amp;gt; a[i])&lt;br /&gt;
           min = j&lt;br /&gt;
       swap(a[i], a[min])&lt;br /&gt;
       reverse(a, i + 1, n - 1)&lt;br /&gt;
       '''return''' a&lt;br /&gt;
   '''return''' ''null'' &lt;br /&gt;
&lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||3||style=&amp;quot;background:#FFCC00&amp;quot;|2||5||style=&amp;quot;background:#FFCC00&amp;quot;|4||исходная перестановка&lt;br /&gt;
|-&lt;br /&gt;
| || ||^|| || ||находим элемент, нарушающий убывающую последовательность&lt;br /&gt;
|-&lt;br /&gt;
| || || || ||^||минимальный элемент больше нашего&lt;br /&gt;
|-&lt;br /&gt;
|1||3||style=&amp;quot;background:#FFCC00&amp;quot;|4||5||style=&amp;quot;background:#FFCC00&amp;quot;|2||меняем их местами&lt;br /&gt;
|-&lt;br /&gt;
|1||3||4||style=&amp;quot;background:#FFCC00&amp;quot;|2||style=&amp;quot;background:#FFCC00&amp;quot;|5||разворачивам правую часть&lt;br /&gt;
|-&lt;br /&gt;
|'''1'''||'''3'''||'''4'''||'''2'''||'''5'''||следующая перестановка&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующей мультиперестановки ==&lt;br /&gt;
* Двигаясь справа налево, находим элемент, нарушающий убывающую последовательность (в обычном порядке, слева направо, см. пример).&lt;br /&gt;
* Меняем его с минимальным элементом, большим нашего, стоящим правее.&lt;br /&gt;
* Переворачиваем правую часть.&lt;br /&gt;
 '''int[]''' nextMultiperm('''int[]''' b):  &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} длина мультиперестановки&amp;lt;/font&amp;gt;&lt;br /&gt;
     i = n - 2&lt;br /&gt;
     '''while''' (i &amp;gt;= 0) '''and''' (b[i] &amp;gt;= b[i + 1]) &lt;br /&gt;
       i--&lt;br /&gt;
     '''if''' i &amp;gt;= 0 &lt;br /&gt;
       j = i + 1&lt;br /&gt;
       '''while''' (j &amp;lt; n - 1) '''and''' (b[j + 1] &amp;gt; b[i]) &lt;br /&gt;
         j++&lt;br /&gt;
       swap(b[i] , b[j])&lt;br /&gt;
       reverse(b, i + 1, n - 1)&lt;br /&gt;
       '''return''' b&lt;br /&gt;
     '''else'''&lt;br /&gt;
       '''return''' ''null''&lt;br /&gt;
&lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||1||style=&amp;quot;background:#FFCC00&amp;quot;|2||style=&amp;quot;background:#FFCC00&amp;quot;|3||Исходная перестановка.&lt;br /&gt;
|-&lt;br /&gt;
| || || || ||^|| ||Находим элемент, нарушающий убывающую последовательность.&lt;br /&gt;
|-&lt;br /&gt;
| || || || || ||^||Минимальный элемент больше нашего.&lt;br /&gt;
|-&lt;br /&gt;
|1||2||3||1||style=&amp;quot;background:#FFCC00&amp;quot;|3||style=&amp;quot;background:#FFCC00&amp;quot;|2||Меняем их местами.&lt;br /&gt;
|-&lt;br /&gt;
|'''1'''||'''2'''||'''3'''||'''1'''||'''3'''||'''2'''||Следующая мультиперестановка.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующего сочетания ==&lt;br /&gt;
&lt;br /&gt;
* Добавим в конец массива с сочетанием &amp;lt;tex&amp;gt;N+1&amp;lt;/tex&amp;gt; – максимальный элемент.&lt;br /&gt;
* Пойдём справа налево. Будем искать номер элемента, который отличается от предыдущего на &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; и больше.&lt;br /&gt;
* Увеличим найденный элемент на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, и допишем в конец минимально возможный хвост, если такого элемента нет – на вход было дано последнее сочетание.&lt;br /&gt;
 '''int[]''' nextChoose('''int[]''' a, '''int''' n, '''int''' k): &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;n,k &amp;lt;/tex&amp;gt; {{---}} параметры сочетания&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''for''' i = 0 '''to''' k - 1 &lt;br /&gt;
     b[i] = a[i]&lt;br /&gt;
   b[k] = n + 1&lt;br /&gt;
   i = k - 1&lt;br /&gt;
   '''while''' (i &amp;gt;= 0) '''and''' (b[i + 1] - b[i] &amp;lt; 2) &lt;br /&gt;
     i--&lt;br /&gt;
   '''if''' i &amp;gt;= 0 &lt;br /&gt;
      b[i]++&lt;br /&gt;
      '''for''' j = i + 1 '''to''' k - 1 &lt;br /&gt;
        b[j] = b[j - 1] + 1&lt;br /&gt;
      '''for''' i = 0 '''to''' k - 1 &lt;br /&gt;
        a[i] = b[i]&lt;br /&gt;
      '''return''' a&lt;br /&gt;
   '''else'''&lt;br /&gt;
     '''return''' ''null''&lt;br /&gt;
&lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||5||6||style=&amp;quot;background:#FFCC00&amp;quot;|'''7'''||Дописываем 7 в конец сочетания.&lt;br /&gt;
|-&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|2||5||6||'''7'''||&lt;br /&gt;
|-&lt;br /&gt;
| ||^|| || || ||Находим элемент i, a[i + 1] - a[ i ] &amp;gt;= 2&lt;br /&gt;
|-&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|3||5||6||'''7'''||Увеличиваем его на 1.&lt;br /&gt;
|-&lt;br /&gt;
|1||3||style=&amp;quot;background:#FFCC00&amp;quot;|4||style=&amp;quot;background:#FFCC00&amp;quot;|5||style=&amp;quot;background:#FFCC00&amp;quot;|'''6'''||Дописываем минимальный хвост.&lt;br /&gt;
|-&lt;br /&gt;
|'''1'''||'''3'''||'''4'''||'''5'''||''' '''||Следующее сочетание.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующего разбиения на слагаемые ==&lt;br /&gt;
Рассматриваемый алгоритм находит следующее [[комбинаторные объекты|разбиение на слагаемые]], при этом разбиение упорядоченно по возрастанию.&lt;br /&gt;
* Увеличим предпоследнее слагаемое на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, уменьшим последнее слагаемое на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
** Если предпоследнее слагаемое стало больше последнего, то увеличиваем предпоследнее слагаемое на величину последнего.&lt;br /&gt;
** Если предпоследнее слагаемое умноженное на 2 меньше последнего, то разбиваем последнее слагаемое &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; на два слагаемых &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; таких, что &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; равно предпоследнему слагаемому, а &amp;lt;tex&amp;gt;b = s - a&amp;lt;/tex&amp;gt;. Повторяем этот процесс, пока разбиение остается корректным, то есть предпоследнее слагаемое хотя бы в два раза меньше последнего.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; {{---}} список, содержащий разбиение данного числа &amp;lt;tex&amp;gt;b.size&amp;lt;/tex&amp;gt;{{---}} его размер &amp;lt;/font&amp;gt;&lt;br /&gt;
 '''list&amp;lt;int&amp;gt;'''  nextPartition('''list&amp;lt;int&amp;gt;''' b): &lt;br /&gt;
    b[b.size - 1]--&lt;br /&gt;
    b[b.size - 2]++&lt;br /&gt;
    '''if''' b[b.size - 2] &amp;gt; b[b.size - 1] &lt;br /&gt;
       b[b.size - 2] += b[b.size - 1]&lt;br /&gt;
       b.remove(b.size - 1)&lt;br /&gt;
    '''else'''&lt;br /&gt;
      '''while''' b[b.size - 2] * 2 &amp;lt;= b[b.size - 1] &lt;br /&gt;
        b.add(b[b.size - 1] - b[b.size - 2])&lt;br /&gt;
        b[b.size - 2] = b[b.size - 3]&lt;br /&gt;
    '''return''' b&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|1||style=&amp;quot;background:#FFCC00&amp;quot;|7|| || ||Прибавим 1 + 1, вычтем 7 - 1.&lt;br /&gt;
|-&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|2||style=&amp;quot;background:#FFCC00&amp;quot;|6|| || ||Проверяем: 2 &amp;lt; 6, значит разбиваем 6 пока оно не станет меньше 4&lt;br /&gt;
|-&lt;br /&gt;
|1||2||style=&amp;quot;background:#FFCC00&amp;quot;|2||style=&amp;quot;background:#FFCC00&amp;quot;|4|| ||&lt;br /&gt;
|-&lt;br /&gt;
|1||2||2||style=&amp;quot;background:#FFCC00&amp;quot;|2||style=&amp;quot;background:#FFCC00&amp;quot;|2||&lt;br /&gt;
|-&lt;br /&gt;
|'''1'''||'''2'''||'''2'''||'''2'''||'''2'''||Следующее разбиение на слагаемые числа 9.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|4||style=&amp;quot;background:#FFCC00&amp;quot;|5||Прибавим 4 + 1, вычтем 5 - 1.&lt;br /&gt;
|-&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|5||style=&amp;quot;background:#FFCC00&amp;quot;|4||Проверяем: 5 &amp;gt; 4, значит прибавим к 5 + 4.&lt;br /&gt;
|-&lt;br /&gt;
|1||9||style=&amp;quot;background:#FFCC00&amp;quot;|4||Удалим последний элемент.&lt;br /&gt;
|-&lt;br /&gt;
|'''1'''||'''9'''||||Следующее разбиение на слагаемые числа 10.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующего разбиения на подмножества ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим множество первых n натуральных чисел:&amp;lt;tex&amp;gt;N_n = \{1, 2, ..., n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Упорядочим все разбиения на множества &amp;lt;tex&amp;gt;N_n&amp;lt;/tex&amp;gt; лексикографически. Для этого, во-первых, в каждом разбиении упорядочим множества лексикографически. Будем говорить, что подмножество &amp;lt;tex&amp;gt; A \subset N_n &amp;lt;/tex&amp;gt; лексикографически меньше подмножества &amp;lt;tex&amp;gt; B \subset N_n &amp;lt;/tex&amp;gt; , если верно одно из следующих условий:&lt;br /&gt;
&lt;br /&gt;
*существует &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; такое, что &amp;lt;tex&amp;gt;i \in A&amp;lt;/tex&amp;gt; , &amp;lt;tex&amp;gt;i \notin B&amp;lt;/tex&amp;gt;, для всех &amp;lt;tex&amp;gt;j &amp;lt; i: j \in A&amp;lt;/tex&amp;gt; если и только если &amp;lt;tex&amp;gt;j \in B&amp;lt;/tex&amp;gt; , и существует &amp;lt;tex&amp;gt;k &amp;gt; i&amp;lt;/tex&amp;gt; такое что &amp;lt;tex&amp;gt;k \in B&amp;lt;/tex&amp;gt;;&lt;br /&gt;
* &amp;lt;tex&amp;gt; A \subset B &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;i &amp;lt; j&amp;lt;/tex&amp;gt; для всех &amp;lt;tex&amp;gt;i \in A&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j \in B&amp;lt;/tex&amp;gt; \ &amp;lt;tex&amp;gt; A &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Разбиения упорядочены лексикографически следующим образом. Разбиение &amp;lt;tex&amp;gt;N_n = A_1 \cup A_2 \cup . . . \cup A_k&amp;lt;/tex&amp;gt; лексикографически меньше разбиения &amp;lt;tex&amp;gt;N_n = B_1 \cup B_2 \cup . . . \cup B_l&amp;lt;/tex&amp;gt; если существует такое &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, что &amp;lt;tex&amp;gt;A_1 = B_1, A_2 = B_2, . . . ,A_{i - 1} = B_{i - 1}, A_i &amp;lt; B_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Рассмотрим алгоритм нахождения лексикографически следующего разбиения на подмножества:'''&lt;br /&gt;
*Будем хранить подмножества в списке списков, например, разбиение &amp;lt;tex&amp;gt; \{1, 2, 3\} ~ \{4, 5\}&amp;lt;/tex&amp;gt; будет выглядеть так:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3&lt;br /&gt;
|-&lt;br /&gt;
|4||5|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* Будем поддерживать массив удалённых элементов {{---}} элементы, которые затем нужно будет вернуть в разбиение.&lt;br /&gt;
&lt;br /&gt;
* Двигаясь снизу вверх будем рассматривать подмножества.&lt;br /&gt;
** Если мы можем дописать в текущее подмножество минимальный элемент из удалённых, то мы нашли следующее разбиение и нужно завершить цикл.&lt;br /&gt;
** Если дописать не можем, значит, либо нужно укоротить и заменить какой-то элемент в текущем подмножестве, либо перейти к следующему подмножеству. Будем идти справа налево и рассматривать элементы:&lt;br /&gt;
*** Если мы можем заменить текущий элемент минимальным удалённым {{---}} мы нашли следующее разбиение, завершаем оба цикла и выполняем алгоритм дальше. Стоит отметить, что нельзя перезаписывать последний элемент в подмножестве, иначе мы не сможем дописать минимальный хвост после этого подмножества {{---}} в удалённых будет элемент меньше текущего и мы не сможем выписать удаленные элементы так, чтобы получилось корректное разбиение.&lt;br /&gt;
*** Если заменить текущий элемент каким-то из удалённых нельзя, то следует удалить и этот.&lt;br /&gt;
* Допишем лексикографически минимальный хвост подмножеств из оставшихся удалённых элементов.&lt;br /&gt;
&lt;br /&gt;
 '''list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;''' nextSetPartition('''list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;''' a):&lt;br /&gt;
   used = '''list&amp;lt;int&amp;gt;'''&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// a {{---}} список, содержащий подмножества&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// used {{---}} список, в котором мы храним удаленные элементы&amp;lt;/font&amp;gt;&lt;br /&gt;
   fl = ''false''&lt;br /&gt;
   '''for''' i = a.size - 1 '''downto''' 0&lt;br /&gt;
     '''if''' (used.size != 0) '''and''' (max(used) &amp;gt; a[i][-1])   &amp;lt;font color=green&amp;gt;// в удалённых есть хотя бы один элемент, который мы можем добавить в конец.&amp;lt;/font&amp;gt;&lt;br /&gt;
       m = '''минимум из''' used '''строго больше''' a[i][-1]&lt;br /&gt;
       a[i].add(m)   &amp;lt;font color=green&amp;gt;//добавляем&amp;lt;/font&amp;gt;&lt;br /&gt;
       used.remove(m)&lt;br /&gt;
       '''break'''&lt;br /&gt;
     '''for''' j = a[i].size - 1 '''downto''' 0&lt;br /&gt;
       '''if''' (used.size != 0) '''and''' (j != 0) '''and''' (max(used) &amp;gt; a[i][j])   &amp;lt;font color=green&amp;gt;//если можем заменить элемент, другим элементом из списка used и он не последний&amp;lt;/font&amp;gt;&lt;br /&gt;
         m = '''минимум из''' used '''строго больше''' a[i][-1]&lt;br /&gt;
         a[i][j] = m   &amp;lt;font color=green&amp;gt;//заменяем&amp;lt;/font&amp;gt;&lt;br /&gt;
         used.remove(m)&lt;br /&gt;
         fl = ''true''&lt;br /&gt;
         '''break'''&lt;br /&gt;
       '''else'''&lt;br /&gt;
         used.add(a[i][-1])&lt;br /&gt;
         a[i].pop()&lt;br /&gt;
         '''if''' a[i].size == 0&lt;br /&gt;
           a.pop()&lt;br /&gt;
      '''if''' fl &lt;br /&gt;
        '''break'''&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;//далее выведем все удалённые, которые не выбрали&amp;lt;/font&amp;gt;&lt;br /&gt;
   sort(used)&lt;br /&gt;
   '''for''' i = 0 '''to''' used.size - 1&lt;br /&gt;
      a.add('''list&amp;lt;int&amp;gt;'''(used[i]))   &amp;lt;font color=green&amp;gt;//добавляем лексикографически минимальных хвост&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''return''' a&lt;br /&gt;
&lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
&lt;br /&gt;
'''Рассмотрим следующее разбиение:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3&lt;br /&gt;
|-&lt;br /&gt;
|4||5|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''1 Шаг:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||&lt;br /&gt;
|-&lt;br /&gt;
|4||style=&amp;quot;background:#FFCC00&amp;quot;|5||||&lt;br /&gt;
|-&lt;br /&gt;
| ||^|| ||Удалили элемент 5.&lt;br /&gt;
|-&lt;br /&gt;
| || || ||Удалённые элементы&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2 Шаг:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#FFCC00&amp;quot;|4|| ||||&lt;br /&gt;
|-&lt;br /&gt;
|^|| || ||Удалили элемент 4. Так как он является последним в подмножестве, то мы не можем заменить его на другой.&lt;br /&gt;
|-&lt;br /&gt;
|5|| || ||Удалённые элементы&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''3 Шаг:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||style=&amp;quot;background:#FFCC00&amp;quot;|4||&lt;br /&gt;
|-&lt;br /&gt;
| || || ||^||Дополнили первое подмножество элементом 4&lt;br /&gt;
|-&lt;br /&gt;
|5|| || || ||Удалённые элементы&lt;br /&gt;
|}  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''4 Шаг:''' &lt;br /&gt;
    &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||4||&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#FFCC00&amp;quot;|5|| || || ||Дописали лексикографически минимальный хвост&lt;br /&gt;
|-&lt;br /&gt;
| || || || ||Удалённые элементы&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== См.также ==&lt;br /&gt;
* [[Получение предыдущего объекта]]&lt;br /&gt;
* [[Получение объекта по номеру]]&lt;br /&gt;
* [[Получение номера по объекту]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
&lt;br /&gt;
* [http://rain.ifmo.ru/cat/view.php/vis/combinations/permutations-2000 Визуализатор перестановок]&lt;br /&gt;
* [http://cppalgo.blogspot.com/2011/02/episode-2.html Пример компактного кода для перестановок (С++)]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Комбинаторика]]&lt;/div&gt;</summary>
		<author><name>Irdkwmnsb</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Irdkwmnsb&amp;diff=76522</id>
		<title>Участник:Irdkwmnsb</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Irdkwmnsb&amp;diff=76522"/>
				<updated>2021-01-07T10:14:12Z</updated>
		
		<summary type="html">&lt;p&gt;Irdkwmnsb: /* Специализация алгоритма для генерации следующего разбиения на подмножества */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Специализация алгоритма для генерации следующего разбиения на подмножества ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим множество первых n натуральных чисел:&amp;lt;tex&amp;gt;N_n = \{1, 2, ..., n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Упорядочим все разбиения на множества &amp;lt;tex&amp;gt;N_n&amp;lt;/tex&amp;gt; лексикографически. Для этого, во-первых, в каждом разбиении упорядочим множества лексикографически. Будем говорить, что подмножество &amp;lt;tex&amp;gt; A \subset N_n &amp;lt;/tex&amp;gt; лексикографически меньше подмножества &amp;lt;tex&amp;gt; B \subset N_n &amp;lt;/tex&amp;gt; , если верно одно из следующих условий:&lt;br /&gt;
&lt;br /&gt;
*существует &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; такое, что &amp;lt;tex&amp;gt;i \in A&amp;lt;/tex&amp;gt; , &amp;lt;tex&amp;gt;i \notin B&amp;lt;/tex&amp;gt;, для всех &amp;lt;tex&amp;gt;j &amp;lt; i: j \in A&amp;lt;/tex&amp;gt; если и только если &amp;lt;tex&amp;gt;j \in B&amp;lt;/tex&amp;gt; , и существует &amp;lt;tex&amp;gt;k &amp;gt; i&amp;lt;/tex&amp;gt; такое что &amp;lt;tex&amp;gt;k \in B&amp;lt;/tex&amp;gt;;&lt;br /&gt;
* &amp;lt;tex&amp;gt; A \subset B &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;i &amp;lt; j&amp;lt;/tex&amp;gt; для всех &amp;lt;tex&amp;gt;i \in A&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j \in B&amp;lt;/tex&amp;gt; \ &amp;lt;tex&amp;gt; A &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Разбиения упорядочены лексикографически следующим образом. Разбиение &amp;lt;tex&amp;gt;N_n = A_1 \cup A_2 \cup . . . \cup A_k&amp;lt;/tex&amp;gt; лексикографически меньше разбиения &amp;lt;tex&amp;gt;N_n = B_1 \cup B_2 \cup . . . \cup B_l&amp;lt;/tex&amp;gt; если существует такое &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, что &amp;lt;tex&amp;gt;A_1 = B_1, A_2 = B_2, . . . ,A_{i - 1} = B_{i - 1}, A_i &amp;lt; B_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Рассмотрим алгоритм нахождения лексикографически следующего разбиения на подмножества:'''&lt;br /&gt;
*Будем хранить подмножества в списке списков, например, разбиение &amp;lt;tex&amp;gt; \{1, 2, 3\} ~ \{4, 5\}&amp;lt;/tex&amp;gt; будет выглядеть так:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3&lt;br /&gt;
|-&lt;br /&gt;
|4||5|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* Будем поддерживать массив удалённых элементов {{---}} элементы, которые затем нужно будет вернуть в разбиение.&lt;br /&gt;
&lt;br /&gt;
* Двигаясь снизу вверх будем рассматривать подмножества.&lt;br /&gt;
** Если мы можем дописать в текущее подмножество минимальный элемент из удалённых, то мы нашли следующее разбиение и нужно завершить цикл.&lt;br /&gt;
** Если дописать не можем, значит, либо нужно укоротить и заменить какой-то элемент в текущем подмножестве, либо перейти к следующему подмножеству. Будем идти справа налево и рассматривать элементы:&lt;br /&gt;
*** Если мы можем заменить текущий элемент минимальным удалённым {{---}} мы нашли следующее разбиение, завершаем оба цикла и выполняем алгоритм дальше. Стоит отметить, что нельзя перезаписывать последний элемент в подмножестве, иначе мы не сможем дописать минимальный хвост после этого подмножества {{---}} в удалённых будет элемент меньше текущего и мы не сможем выписать удаленные элементы так, чтобы получилось корректное разбиение.&lt;br /&gt;
*** Если заменить текущий элемент каким-то из удалённых нельзя, то следует удалить и этот.&lt;br /&gt;
* Допишем лексикографически минимальный хвост подмножеств из оставшихся удалённых элементов.&lt;br /&gt;
&lt;br /&gt;
 '''list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;''' nextSetPartition('''list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;''' a):&lt;br /&gt;
   used = '''list&amp;lt;int&amp;gt;'''&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// a {{---}} список, содержащий подмножества&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// used {{---}} список, в котором мы храним удаленные элементы&amp;lt;/font&amp;gt;&lt;br /&gt;
   fl = ''false''&lt;br /&gt;
   '''for''' i = a.size - 1 '''downto''' 0&lt;br /&gt;
     '''if''' (used.size != 0) '''and''' (max(used) &amp;gt; a[i][-1])   &amp;lt;font color=green&amp;gt;// в удалённых есть хотя бы один элемент, который мы можем добавить в конец.&amp;lt;/font&amp;gt;&lt;br /&gt;
       m = '''минимум из''' used '''строго больше''' a[i][-1]&lt;br /&gt;
       a[i].add(m)   &amp;lt;font color=green&amp;gt;//добавляем&amp;lt;/font&amp;gt;&lt;br /&gt;
       used.remove(m)&lt;br /&gt;
       '''break'''&lt;br /&gt;
     '''for''' j = a[i].size - 1 '''downto''' 0&lt;br /&gt;
       '''if''' (used.size != 0) '''and''' (j != 0) '''and''' (max(used) &amp;gt; a[i][j])   &amp;lt;font color=green&amp;gt;//если можем заменить элемент, другим элементом из списка used и он не последний&amp;lt;/font&amp;gt;&lt;br /&gt;
         m = '''минимум из''' used '''строго больше''' a[i][-1]&lt;br /&gt;
         a[i][j] = m   &amp;lt;font color=green&amp;gt;//заменяем&amp;lt;/font&amp;gt;&lt;br /&gt;
         used.remove(m)&lt;br /&gt;
         fl = ''true''&lt;br /&gt;
         '''break'''&lt;br /&gt;
       '''else'''&lt;br /&gt;
         used.add(a[i][-1])&lt;br /&gt;
         a[i].pop()&lt;br /&gt;
         '''if''' a[i].size == 0&lt;br /&gt;
           a.pop()&lt;br /&gt;
      '''if''' fl &lt;br /&gt;
        '''break'''&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;//далее выведем все удалённые, которые не выбрали&amp;lt;/font&amp;gt;&lt;br /&gt;
   sort(used)&lt;br /&gt;
   '''for''' i = 0 '''to''' used.size - 1&lt;br /&gt;
      a.add('''list&amp;lt;int&amp;gt;'''(used[i]))   &amp;lt;font color=green&amp;gt;//добавляем лексикографически минимальных хвост&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''return''' a&lt;br /&gt;
&lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
&lt;br /&gt;
'''Рассмотрим следующее разбиение:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3&lt;br /&gt;
|-&lt;br /&gt;
|4||5|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''1 Шаг:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||&lt;br /&gt;
|-&lt;br /&gt;
|4||style=&amp;quot;background:#FFCC00&amp;quot;|5||||&lt;br /&gt;
|-&lt;br /&gt;
| ||^|| ||Удалили элемент 5.&lt;br /&gt;
|-&lt;br /&gt;
| || || ||Удалённые элементы&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2 Шаг:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#FFCC00&amp;quot;|4|| ||||&lt;br /&gt;
|-&lt;br /&gt;
|^|| || ||Удалили элемент 4. Так как он является последним в подмножестве, то мы не можем заменить его на другой.&lt;br /&gt;
|-&lt;br /&gt;
|5|| || ||Удалённые элементы&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''3 Шаг:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||style=&amp;quot;background:#FFCC00&amp;quot;|4||&lt;br /&gt;
|-&lt;br /&gt;
| || || ||^||Дополнили первое подмножество элементом 4&lt;br /&gt;
|-&lt;br /&gt;
|5|| || || ||Удалённые элементы&lt;br /&gt;
|}  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''4 Шаг:''' &lt;br /&gt;
    &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||4||&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#FFCC00&amp;quot;|5|| || || ||Дописали лексикографически минимальный хвост&lt;br /&gt;
|-&lt;br /&gt;
| || || || ||Удалённые элементы&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Irdkwmnsb</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Irdkwmnsb&amp;diff=76499</id>
		<title>Участник:Irdkwmnsb</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Irdkwmnsb&amp;diff=76499"/>
				<updated>2021-01-06T18:24:20Z</updated>
		
		<summary type="html">&lt;p&gt;Irdkwmnsb: fixes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Специализация алгоритма для генерации следующего разбиения на подмножества ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим множество первых n натуральных чисел:&amp;lt;tex&amp;gt;N_n = \{1, 2, ..., n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Упорядочим все разбиения на множества &amp;lt;tex&amp;gt;N_n&amp;lt;/tex&amp;gt; лексикографически. Для этого, во-первых, в каждом разбиении упорядочим множества лексикографически. Будем говорить, что подмножество &amp;lt;tex&amp;gt; A \subset N_n &amp;lt;/tex&amp;gt; лексикографически меньше подмножества &amp;lt;tex&amp;gt; B \subset N_n &amp;lt;/tex&amp;gt; , если верно одно из следующих условий:&lt;br /&gt;
&lt;br /&gt;
*существует &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; такое, что &amp;lt;tex&amp;gt;i \in A&amp;lt;/tex&amp;gt; , &amp;lt;tex&amp;gt;i \notin B&amp;lt;/tex&amp;gt;, для всех &amp;lt;tex&amp;gt;j &amp;lt; i: j \in A&amp;lt;/tex&amp;gt; если и только если &amp;lt;tex&amp;gt;j \in B&amp;lt;/tex&amp;gt; , и существует &amp;lt;tex&amp;gt;k &amp;gt; i&amp;lt;/tex&amp;gt; такое что &amp;lt;tex&amp;gt;k \in B&amp;lt;/tex&amp;gt;;&lt;br /&gt;
* &amp;lt;tex&amp;gt; A \subset B &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;i &amp;lt; j&amp;lt;/tex&amp;gt; для всех &amp;lt;tex&amp;gt;i \in A&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j \in B&amp;lt;/tex&amp;gt; \ &amp;lt;tex&amp;gt; A &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Разбиения упорядочены лексикографически следующим образом. Разбиение &amp;lt;tex&amp;gt;N_n = A_1 \cup A_2 \cup . . . \cup A_k&amp;lt;/tex&amp;gt; лексикографически меньше разбиения &amp;lt;tex&amp;gt;N_n = B_1 \cup B_2 \cup . . . \cup B_l&amp;lt;/tex&amp;gt; если существует такое &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, что &amp;lt;tex&amp;gt;A_1 = B_1, A_2 = B_2, . . . ,A_{i - 1} = B_{i - 1}, A_i &amp;lt; B_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Рассмотрим алгоритм нахождения лексикографически следующего разбиения на подмножества:'''&lt;br /&gt;
*Будем хранить подмножества в списке списков, например, разбиение &amp;lt;tex&amp;gt; \{1, 2, 3\}~ \{4, 5\}&amp;lt;/tex&amp;gt; будет выглядеть так:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3&lt;br /&gt;
|-&lt;br /&gt;
|4||5|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* Будем поддерживать массив &amp;quot;удалённых&amp;quot; элементов {{---}} элементы которые затем нужно будет вернуть в разбиение.&lt;br /&gt;
&lt;br /&gt;
* Двигаясь снизу вверх будем рассматривать подмножества.&lt;br /&gt;
** Если мы можем дописать в текущее подмножество минимальный элемент из удалённых, то мы нашли следующее разбиение и нужно завершить цикл.&lt;br /&gt;
** Если дописать не можем, значит, либо нужно укоротить и заменить какой то элемент в текущем подмножестве, либо перейти к следующему подмножеству. Будем идти справа налево и рассматривать элементы:&lt;br /&gt;
*** Если мы можем заменить текущий элемент минимальным удалённым {{---}} мы нашли следующее разбиение, завершаем оба цикла и выполняем алгоритм дальше. Стоит отметить, что нельзя перезаписывать последний элемент в подмножестве, иначе мы не сможем дописать минимальный хвост после этого подмножества {{---}} в удалённых будет элемент меньше текущего и мы не сможем выписать удаленные элементы так, чтобы получилось корректное разбиение.&lt;br /&gt;
*** Если заменить текущий элемент каким то из удалённых нельзя, то следует удалить и этот.&lt;br /&gt;
* Допишем лексикографически минимальный хвост подмножеств из оставшихся удалённых элементов.&lt;br /&gt;
&lt;br /&gt;
 '''list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;''' nextSetPartition('''list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;''' a):&lt;br /&gt;
   used = '''list&amp;lt;int&amp;gt;'''&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// a {{---}} список, содержащий подмножества&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// used {{---}} список, в котором мы храним удаленные элементы&amp;lt;/font&amp;gt;&lt;br /&gt;
   fl = ''false''&lt;br /&gt;
   '''for''' i = a.size - 1 '''downto''' 0&lt;br /&gt;
     '''if''' (used.size != 0) '''and''' (max(used) &amp;gt; a[i][-1])   &amp;lt;font color=green&amp;gt;// в удалённых есть хотя бы один элемент, который мы можем добавить в конец.&amp;lt;/font&amp;gt;&lt;br /&gt;
       m = '''минимум из''' used '''строго больше''' a[i][-1]&lt;br /&gt;
       a[i].add(m)   &amp;lt;font color=green&amp;gt;//добавляем&amp;lt;/font&amp;gt;&lt;br /&gt;
       used.remove(m)&lt;br /&gt;
       '''break'''&lt;br /&gt;
     '''for''' j = a[i].size - 1 '''downto''' 0&lt;br /&gt;
       '''if''' (used.size != 0) '''and''' (j != 0) '''and''' (max(used) &amp;gt; a[i][j])   &amp;lt;font color=green&amp;gt;//если можем заменить элемент, другим элементом из списка used и он не последний&amp;lt;/font&amp;gt;&lt;br /&gt;
         m = '''минимум из''' used '''строго больше''' a[i][-1]&lt;br /&gt;
         a[i][j] = m   &amp;lt;font color=green&amp;gt;//заменяем&amp;lt;/font&amp;gt;&lt;br /&gt;
         used.remove(m)&lt;br /&gt;
         fl = ''true''&lt;br /&gt;
         '''break'''&lt;br /&gt;
       '''else'''&lt;br /&gt;
         used.add(a[i][-1])&lt;br /&gt;
         a[i].pop()&lt;br /&gt;
         '''if''' a[i].size == 0&lt;br /&gt;
           a.pop()&lt;br /&gt;
      '''if''' fl &lt;br /&gt;
        '''break'''&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;//далее выведем все удалённые, которые не выбрали&amp;lt;/font&amp;gt;&lt;br /&gt;
   sort(used)&lt;br /&gt;
   '''for''' i = 0 '''to''' used.size - 1&lt;br /&gt;
      a.add('''list&amp;lt;int&amp;gt;'''(used[i]))   &amp;lt;font color=green&amp;gt;//добавляем лексикографически минимальных хвост&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''return''' a&lt;br /&gt;
&lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
&lt;br /&gt;
'''Рассмотрим следующее разбиение:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3&lt;br /&gt;
|-&lt;br /&gt;
|4||5|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''1 Шаг:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||&lt;br /&gt;
|-&lt;br /&gt;
|4||style=&amp;quot;background:#FFCC00&amp;quot;|5||||&lt;br /&gt;
|-&lt;br /&gt;
| ||^|| ||Удалили элемент 5.&lt;br /&gt;
|-&lt;br /&gt;
| || || ||Удалённые элементы&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2 Шаг:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#FFCC00&amp;quot;|4|| ||||&lt;br /&gt;
|-&lt;br /&gt;
|^|| || ||Удалили элемент 4. Так как он является последним в подмножестве, то мы не можем заменить его на другой.&lt;br /&gt;
|-&lt;br /&gt;
|5|| || ||Удалённые элементы&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''3 Шаг:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||style=&amp;quot;background:#FFCC00&amp;quot;|4||&lt;br /&gt;
|-&lt;br /&gt;
| || || ||^||Дополнили первое подмножество элементом 4&lt;br /&gt;
|-&lt;br /&gt;
|5|| || || ||Удалённые элементы&lt;br /&gt;
|}  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''4 Шаг:''' &lt;br /&gt;
    &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||4||&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#FFCC00&amp;quot;|5|| || || ||Дописали лексикографически минимальный хвост&lt;br /&gt;
|-&lt;br /&gt;
| || || || ||Удалённые элементы&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Irdkwmnsb</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D1%81%D0%BB%D0%B5%D0%B4%D1%83%D1%8E%D1%89%D0%B5%D0%B3%D0%BE_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%B0&amp;diff=75936</id>
		<title>Получение следующего объекта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D1%81%D0%BB%D0%B5%D0%B4%D1%83%D1%8E%D1%89%D0%B5%D0%B3%D0%BE_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%B0&amp;diff=75936"/>
				<updated>2021-01-01T17:09:12Z</updated>
		
		<summary type="html">&lt;p&gt;Irdkwmnsb: Отмена правки 75934, сделанной Irdkwmnsb (обсуждение)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Алгоритм ==&lt;br /&gt;
{{Определение|definition= '''Получение следующего объекта''' {{---}} это нахождение объекта, следующего за данным в [[Лексикографический порядок|лексикографическом порядке]].&lt;br /&gt;
}}&lt;br /&gt;
Объект &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; называется следующим за &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;P &amp;lt; Q&amp;lt;/tex&amp;gt; и не найдется такого &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt;, что &amp;lt;tex&amp;gt;P &amp;lt; R &amp;lt; Q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Отсюда понятен алгоритм:&lt;br /&gt;
* находим суффикс минимальной длины, который можно изменить без изменения префикса текущего объекта &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* к оставшейся части дописываем минимальный возможный элемент (чтобы было выполнено правило &amp;lt;tex&amp;gt;P &amp;lt; Q&amp;lt;/tex&amp;gt;),&lt;br /&gt;
* дописываем минимальный возможный хвост.&lt;br /&gt;
По построению получаем, что &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; {{---}} минимально возможный.&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующего битового вектора ==&lt;br /&gt;
* Находим минимальный суффикс, в котором есть &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, его можно увеличить, не меняя оставшейся части&lt;br /&gt;
* Вместо &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; записываем &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; &lt;br /&gt;
* Дописываем минимально возможный хвост из нулей&lt;br /&gt;
 '''int[]''' nextVector('''int[]''' a): &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} длина вектора&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''while''' (n &amp;gt;= 0) '''and''' (a[n] != 0)&lt;br /&gt;
       a[n] = 0&lt;br /&gt;
       n--&lt;br /&gt;
   '''if''' n == -1&lt;br /&gt;
     '''return''' ''null''&lt;br /&gt;
   a[n] = 1&lt;br /&gt;
   '''return''' a&lt;br /&gt;
Приведённый алгоритм эквивалентен прибавлению единицы к битовому вектору. &lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|0||1||0||1||style=&amp;quot;background:#FFCC00&amp;quot;|1||исходный битовый вектор&lt;br /&gt;
|-&lt;br /&gt;
| || || || ||^|| начинаем идти с конца&lt;br /&gt;
|-&lt;br /&gt;
|0||1||0||style=&amp;quot;background:#FFCC00&amp;quot;|0||style=&amp;quot;background:#FFCC00&amp;quot;|0|| пока элементы равны 1, заменяем их на 0&lt;br /&gt;
|-&lt;br /&gt;
|0||1||style=&amp;quot;background:#FFCC00&amp;quot;|1||0||0|| меняем первый не удовлетворяющий условию цикла элемент на 1&lt;br /&gt;
|-&lt;br /&gt;
|'''0'''||'''1'''||'''1'''||'''0'''||'''0'''||следующий битовый вектор&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующей перестановки ==&lt;br /&gt;
* Двигаясь справа налево, находим элемент, нарушающий убывающую последовательность (в обычном порядке, слева направо, см. пример)&lt;br /&gt;
* Меняем его с минимальным элементом, большим нашего, стоящим правее&lt;br /&gt;
* Перевернем правую часть&lt;br /&gt;
&lt;br /&gt;
 '''int[]''' nextPermutation('''int[]''' a): &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} длина перестановки&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''for''' i = n - 2 '''downto''' 0&lt;br /&gt;
     '''if''' a[i] &amp;lt; a[i + 1]&lt;br /&gt;
       min = i + 1;&lt;br /&gt;
       '''for''' j = i + 1 '''to''' n - 1&lt;br /&gt;
         '''if''' (a[j] &amp;lt; a[min]) '''and''' (a[j] &amp;gt; a[i])&lt;br /&gt;
           min = j&lt;br /&gt;
       swap(a[i], a[min])&lt;br /&gt;
       reverse(a, i + 1, n - 1)&lt;br /&gt;
       '''return''' a&lt;br /&gt;
   '''return''' ''null'' &lt;br /&gt;
&lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||3||style=&amp;quot;background:#FFCC00&amp;quot;|2||5||style=&amp;quot;background:#FFCC00&amp;quot;|4||исходная перестановка&lt;br /&gt;
|-&lt;br /&gt;
| || ||^|| || ||находим элемент, нарушающий убывающую последовательность&lt;br /&gt;
|-&lt;br /&gt;
| || || || ||^||минимальный элемент больше нашего&lt;br /&gt;
|-&lt;br /&gt;
|1||3||style=&amp;quot;background:#FFCC00&amp;quot;|4||5||style=&amp;quot;background:#FFCC00&amp;quot;|2||меняем их местами&lt;br /&gt;
|-&lt;br /&gt;
|1||3||4||style=&amp;quot;background:#FFCC00&amp;quot;|2||style=&amp;quot;background:#FFCC00&amp;quot;|5||разворачивам правую часть&lt;br /&gt;
|-&lt;br /&gt;
|'''1'''||'''3'''||'''4'''||'''2'''||'''5'''||следующая перестановка&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующей мультиперестановки ==&lt;br /&gt;
* Двигаясь справа налево, находим элемент, нарушающий убывающую последовательность (в обычном порядке, слева направо, см. пример).&lt;br /&gt;
* Меняем его с минимальным элементом, большим нашего, стоящим правее.&lt;br /&gt;
* Переворачиваем правую часть.&lt;br /&gt;
 '''int[]''' nextMultiperm('''int[]''' b):  &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} длина мультиперестановки&amp;lt;/font&amp;gt;&lt;br /&gt;
     i = n - 2&lt;br /&gt;
     '''while''' (i &amp;gt;= 0) '''and''' (b[i] &amp;gt;= b[i + 1]) &lt;br /&gt;
       i--&lt;br /&gt;
     '''if''' i &amp;gt;= 0 &lt;br /&gt;
       j = i + 1&lt;br /&gt;
       '''while''' (j &amp;lt; n - 1) '''and''' (b[j + 1] &amp;gt; b[i]) &lt;br /&gt;
         j++&lt;br /&gt;
       swap(b[i] , b[j])&lt;br /&gt;
       reverse(b, i + 1, n - 1)&lt;br /&gt;
       '''return''' b&lt;br /&gt;
     '''else'''&lt;br /&gt;
       '''return''' ''null''&lt;br /&gt;
&lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||1||style=&amp;quot;background:#FFCC00&amp;quot;|2||style=&amp;quot;background:#FFCC00&amp;quot;|3||Исходная перестановка.&lt;br /&gt;
|-&lt;br /&gt;
| || || || ||^|| ||Находим элемент, нарушающий убывающую последовательность.&lt;br /&gt;
|-&lt;br /&gt;
| || || || || ||^||Минимальный элемент больше нашего.&lt;br /&gt;
|-&lt;br /&gt;
|1||2||3||1||style=&amp;quot;background:#FFCC00&amp;quot;|3||style=&amp;quot;background:#FFCC00&amp;quot;|2||Меняем их местами.&lt;br /&gt;
|-&lt;br /&gt;
|'''1'''||'''2'''||'''3'''||'''1'''||'''3'''||'''2'''||Следующая мультиперестановка.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующего сочетания ==&lt;br /&gt;
&lt;br /&gt;
* Добавим в конец массива с сочетанием &amp;lt;tex&amp;gt;N+1&amp;lt;/tex&amp;gt; – максимальный элемент.&lt;br /&gt;
* Пойдём справа налево. Будем искать номер элемента, который отличается от предыдущего на &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; и больше.&lt;br /&gt;
* Увеличим найденный элемент на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, и допишем в конец минимально возможный хвост, если такого элемента нет – на вход было дано последнее сочетание.&lt;br /&gt;
 '''int[]''' nextChoose('''int[]''' a, '''int''' n, '''int''' k): &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;n,k &amp;lt;/tex&amp;gt; {{---}} параметры сочетания&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''for''' i = 0 '''to''' k - 1 &lt;br /&gt;
     b[i] = a[i]&lt;br /&gt;
   b[k] = n + 1&lt;br /&gt;
   i = k - 1&lt;br /&gt;
   '''while''' (i &amp;gt;= 0) '''and''' (b[i + 1] - b[i] &amp;lt; 2) &lt;br /&gt;
     i--&lt;br /&gt;
   '''if''' i &amp;gt;= 0 &lt;br /&gt;
      b[i]++&lt;br /&gt;
      '''for''' j = i + 1 '''to''' k - 1 &lt;br /&gt;
        b[j] = b[j - 1] + 1&lt;br /&gt;
      '''for''' i = 0 '''to''' k - 1 &lt;br /&gt;
        a[i] = b[i]&lt;br /&gt;
      '''return''' a&lt;br /&gt;
   '''else'''&lt;br /&gt;
     '''return''' ''null''&lt;br /&gt;
&lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||5||6||style=&amp;quot;background:#FFCC00&amp;quot;|'''7'''||Дописываем 7 в конец сочетания.&lt;br /&gt;
|-&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|2||5||6||'''7'''||&lt;br /&gt;
|-&lt;br /&gt;
| ||^|| || || ||Находим элемент i, a[i + 1] - a[ i ] &amp;gt;= 2&lt;br /&gt;
|-&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|3||5||6||'''7'''||Увеличиваем его на 1.&lt;br /&gt;
|-&lt;br /&gt;
|1||3||style=&amp;quot;background:#FFCC00&amp;quot;|4||style=&amp;quot;background:#FFCC00&amp;quot;|5||style=&amp;quot;background:#FFCC00&amp;quot;|'''6'''||Дописываем минимальный хвост.&lt;br /&gt;
|-&lt;br /&gt;
|'''1'''||'''3'''||'''4'''||'''5'''||''' '''||Следующее сочетание.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующего разбиения на слагаемые ==&lt;br /&gt;
Рассматриваемый алгоритм находит следующее [[комбинаторные объекты|разбиение на слагаемые]], при этом разбиение упорядоченно по возрастанию.&lt;br /&gt;
* Увеличим предпоследнее слагаемое на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, уменьшим последнее слагаемое на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
** Если предпоследнее слагаемое стало больше последнего, то увеличиваем предпоследнее слагаемое на величину последнего.&lt;br /&gt;
** Если предпоследнее слагаемое умноженное на 2 меньше последнего, то разбиваем последнее слагаемое &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; на два слагаемых &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; таких, что &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; равно предпоследнему слагаемому, а &amp;lt;tex&amp;gt;b = s - a&amp;lt;/tex&amp;gt;. Повторяем этот процесс, пока разбиение остается корректным, то есть предпоследнее слагаемое хотя бы в два раза меньше последнего.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; {{---}} список, содержащий разбиение данного числа &amp;lt;tex&amp;gt;b.size&amp;lt;/tex&amp;gt;{{---}} его размер &amp;lt;/font&amp;gt;&lt;br /&gt;
 '''list&amp;lt;int&amp;gt;'''  nextPartition('''list&amp;lt;int&amp;gt;''' b): &lt;br /&gt;
    b[b.size - 1]--&lt;br /&gt;
    b[b.size - 2]++&lt;br /&gt;
    '''if''' b[b.size - 2] &amp;gt; b[b.size - 1] &lt;br /&gt;
       b[b.size - 2] += b[b.size - 1]&lt;br /&gt;
       b.remove(b.size - 1)&lt;br /&gt;
    '''else'''&lt;br /&gt;
      '''while''' b[b.size - 2] * 2 &amp;lt;= b[b.size - 1] &lt;br /&gt;
        b.add(b[b.size - 1] - b[b.size - 2])&lt;br /&gt;
        b[b.size - 2] = b[b.size - 3]&lt;br /&gt;
    '''return''' b&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|1||style=&amp;quot;background:#FFCC00&amp;quot;|7|| || ||Прибавим 1 + 1, вычтем 7 - 1.&lt;br /&gt;
|-&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|2||style=&amp;quot;background:#FFCC00&amp;quot;|6|| || ||Проверяем: 2 &amp;lt; 6, значит разбиваем 6 пока оно не станет меньше 4&lt;br /&gt;
|-&lt;br /&gt;
|1||2||style=&amp;quot;background:#FFCC00&amp;quot;|2||style=&amp;quot;background:#FFCC00&amp;quot;|4|| ||&lt;br /&gt;
|-&lt;br /&gt;
|1||2||2||style=&amp;quot;background:#FFCC00&amp;quot;|2||style=&amp;quot;background:#FFCC00&amp;quot;|2||&lt;br /&gt;
|-&lt;br /&gt;
|'''1'''||'''2'''||'''2'''||'''2'''||'''2'''||Следующее разбиение на слагаемые числа 9.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|4||style=&amp;quot;background:#FFCC00&amp;quot;|5||Прибавим 4 + 1, вычтем 5 - 1.&lt;br /&gt;
|-&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|5||style=&amp;quot;background:#FFCC00&amp;quot;|4||Проверяем: 5 &amp;gt; 4, значит прибавим к 5 + 4.&lt;br /&gt;
|-&lt;br /&gt;
|1||9||style=&amp;quot;background:#FFCC00&amp;quot;|4||Удалим последний элемент.&lt;br /&gt;
|-&lt;br /&gt;
|'''1'''||'''9'''||||Следующее разбиение на слагаемые числа 10.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующего разбиения на подмножества ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим множество первых n натуральных чисел:&amp;lt;tex&amp;gt;N_n = \{1, 2, ..., n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Упорядочим все разбиения на множества &amp;lt;tex&amp;gt;N_n&amp;lt;/tex&amp;gt; лексикографически. Для этого, во-первых, в каждом разбиении упорядочим множества лексикографически. Будем говорить, что подмножество &amp;lt;tex&amp;gt; A \subset N_n &amp;lt;/tex&amp;gt; лексикографически меньше подмножества &amp;lt;tex&amp;gt; B \subset N_n &amp;lt;/tex&amp;gt; , если верно одно из следующих условий:&lt;br /&gt;
&lt;br /&gt;
*существует &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; такое, что &amp;lt;tex&amp;gt;i \in A&amp;lt;/tex&amp;gt; , &amp;lt;tex&amp;gt;i \notin B&amp;lt;/tex&amp;gt;, для всех &amp;lt;tex&amp;gt;j &amp;lt; i: j \in A&amp;lt;/tex&amp;gt; если и только если &amp;lt;tex&amp;gt;j \in B&amp;lt;/tex&amp;gt; , и существует &amp;lt;tex&amp;gt;k &amp;gt; i&amp;lt;/tex&amp;gt; такое что &amp;lt;tex&amp;gt;k \in B&amp;lt;/tex&amp;gt;;&lt;br /&gt;
* &amp;lt;tex&amp;gt; A \subset B &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;i &amp;lt; j&amp;lt;/tex&amp;gt; для всех &amp;lt;tex&amp;gt;i \in A&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j \in B&amp;lt;/tex&amp;gt; \ &amp;lt;tex&amp;gt; A &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Разбиения упорядочены лексикографически следующим образом. Разбиение &amp;lt;tex&amp;gt;N_n = A_1 \cup A_2 \cup . . . \cup A_k&amp;lt;/tex&amp;gt; лексикографически меньше разбиения &amp;lt;tex&amp;gt;N_n = B_1 \cup B_2 \cup . . . \cup B_l&amp;lt;/tex&amp;gt; если существует такое &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, что &amp;lt;tex&amp;gt;A_1 = B_1, A_2 = B_2, . . . ,A_{i - 1} = B_{i - 1}, A_i &amp;lt; B_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Рассмотрим алгоритм нахождения лексикографически следующего разбиения на подмножества:'''&lt;br /&gt;
*Будем хранить подмножества в списке списков, например, разбиение &amp;lt;tex&amp;gt; \{1, 2, 3\}~ \{4, 5\}&amp;lt;/tex&amp;gt; будет выглядеть так:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3&lt;br /&gt;
|-&lt;br /&gt;
|4||5|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* Двигаясь снизу вверх и справа налево, будем удалять элементы, записывая их в отдельный массив. Будем повторять эту операцию, пока не сможем выполнить одно из действий, описанных ниже:&lt;br /&gt;
** Заменить рассматриваемый элемент уже удаленным. Из всех подходящих элементов выбираем минимальный. '''Важное замечание''': мы не можем заменить первый элемент подмножества, мы можем только удалить его.&lt;br /&gt;
** Дополнить рассматриваемое подмножество уже удаленным элементом. Из всех подходящих элементов выбираем минимальный.&lt;br /&gt;
* Допишем лексикографически минимальный хвост подмножеств из оставшихся элементов.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 '''list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;''' nextSetPartition('''list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;''' a):&lt;br /&gt;
  &amp;lt;font color=green&amp;gt;// a {{---}} список, содержащий подмножества&amp;lt;/font&amp;gt;&lt;br /&gt;
  &amp;lt;font color=green&amp;gt;// used {{---}} список, в котором мы храним удаленные элементы&amp;lt;/font&amp;gt;&lt;br /&gt;
  used = '''list&amp;lt;int&amp;gt;'''&lt;br /&gt;
  fl = ''false''&lt;br /&gt;
  '''for''' i = a.size - 1 '''downto''' 0&lt;br /&gt;
      '''if''' (used.size != 0) '''and''' (used[used.size - 1] &amp;gt; a[i][a[i].size - 1])   &amp;lt;font color=green&amp;gt;// если можем добавить в конец подмножества элемент из used&amp;lt;/font&amp;gt;&lt;br /&gt;
          a[i].add(used[used.size - 1])   &amp;lt;font color=green&amp;gt;//добавляем&amp;lt;/font&amp;gt;&lt;br /&gt;
          used.remove(used.size - 1)&lt;br /&gt;
          '''break'''&lt;br /&gt;
      '''for''' j = a[i].size - 1 '''downto''' 0&lt;br /&gt;
          '''if''' (used.size != 0) '''and''' (j != 0) '''and''' (used[used.size - 1] &amp;gt; a[i][j])    &amp;lt;font color=green&amp;gt;//если можем заменить элемент, другим элементом из списка used &amp;lt;/font&amp;gt;&lt;br /&gt;
             a[i][j] = used[used.size - 1]   &amp;lt;font color=green&amp;gt;//заменяем&amp;lt;/font&amp;gt;&lt;br /&gt;
             fl = ''true''&lt;br /&gt;
             '''break'''&lt;br /&gt;
      '''if''' fl '''break'''&lt;br /&gt;
      used.add(a[i][j])   &amp;lt;font color=green&amp;gt;//добавляем в used j-й элемент i-го подмножества&amp;lt;/font&amp;gt; &lt;br /&gt;
      a[i].remove(j)   &amp;lt;font color=green&amp;gt;//удаляем j-й элемент i-го подмножества&amp;lt;/font&amp;gt;&lt;br /&gt;
  &amp;lt;font color=green&amp;gt;//далее выведем все получившиеся подмножества&amp;lt;/font&amp;gt;&lt;br /&gt;
  sort(used)&lt;br /&gt;
  '''for''' i = 0 '''to''' used.size - 1&lt;br /&gt;
     a.add('''list&amp;lt;int&amp;gt;'''(used[i]))   &amp;lt;font color=green&amp;gt;//добавляем лексикографически минимальных хвост&amp;lt;/font&amp;gt;&lt;br /&gt;
  '''return''' a&lt;br /&gt;
&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
&lt;br /&gt;
'''Рассмотрим следующее разбиение:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3&lt;br /&gt;
|-&lt;br /&gt;
|4||5|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''1 Шаг:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||&lt;br /&gt;
|-&lt;br /&gt;
|4||style=&amp;quot;background:#FFCC00&amp;quot;|5||||&lt;br /&gt;
|-&lt;br /&gt;
| ||^|| ||Удалили элемент 5.&lt;br /&gt;
|-&lt;br /&gt;
| || || ||used&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2 Шаг:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#FFCC00&amp;quot;|4|| ||||&lt;br /&gt;
|-&lt;br /&gt;
|^|| || ||Удалили элемент 4. Так как он является первым в подмножестве, то мы не можем заменить его на другой.&lt;br /&gt;
|-&lt;br /&gt;
|5|| || ||used&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''3 Шаг:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||style=&amp;quot;background:#FFCC00&amp;quot;|4||&lt;br /&gt;
|-&lt;br /&gt;
| || || ||^||Дополнили первое подмножество элементом 4&lt;br /&gt;
|-&lt;br /&gt;
|5|| || || ||used&lt;br /&gt;
|}  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''4 Шаг:''' &lt;br /&gt;
     &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||4||&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#FFCC00&amp;quot;|5|| || || ||Дописали лексикографически минимальный хвост&lt;br /&gt;
|-&lt;br /&gt;
| || || || ||used&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== См.также ==&lt;br /&gt;
* [[Получение предыдущего объекта]]&lt;br /&gt;
* [[Получение объекта по номеру]]&lt;br /&gt;
* [[Получение номера по объекту]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
&lt;br /&gt;
* [http://rain.ifmo.ru/cat/view.php/vis/combinations/permutations-2000 Визуализатор перестановок]&lt;br /&gt;
* [http://cppalgo.blogspot.com/2011/02/episode-2.html Пример компактного кода для перестановок (С++)]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Комбинаторика]]&lt;/div&gt;</summary>
		<author><name>Irdkwmnsb</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Irdkwmnsb&amp;diff=75935</id>
		<title>Участник:Irdkwmnsb</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Irdkwmnsb&amp;diff=75935"/>
				<updated>2021-01-01T17:08:48Z</updated>
		
		<summary type="html">&lt;p&gt;Irdkwmnsb: submit&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Специализация алгоритма для генерации следующего разбиения на подмножества ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим множество первых n натуральных чисел:&amp;lt;tex&amp;gt;N_n = \{1, 2, ..., n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Упорядочим все разбиения на множества &amp;lt;tex&amp;gt;N_n&amp;lt;/tex&amp;gt; лексикографически. Для этого, во-первых, в каждом разбиении упорядочим множества лексикографически. Будем говорить, что подмножество &amp;lt;tex&amp;gt; A \subset N_n &amp;lt;/tex&amp;gt; лексикографически меньше подмножества &amp;lt;tex&amp;gt; B \subset N_n &amp;lt;/tex&amp;gt; , если верно одно из следующих условий:&lt;br /&gt;
&lt;br /&gt;
*существует &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; такое, что &amp;lt;tex&amp;gt;i \in A&amp;lt;/tex&amp;gt; , &amp;lt;tex&amp;gt;i \notin B&amp;lt;/tex&amp;gt;, для всех &amp;lt;tex&amp;gt;j &amp;lt; i: j \in A&amp;lt;/tex&amp;gt; если и только если &amp;lt;tex&amp;gt;j \in B&amp;lt;/tex&amp;gt; , и существует &amp;lt;tex&amp;gt;k &amp;gt; i&amp;lt;/tex&amp;gt; такое что &amp;lt;tex&amp;gt;k \in B&amp;lt;/tex&amp;gt;;&lt;br /&gt;
* &amp;lt;tex&amp;gt; A \subset B &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;i &amp;lt; j&amp;lt;/tex&amp;gt; для всех &amp;lt;tex&amp;gt;i \in A&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j \in B&amp;lt;/tex&amp;gt; \ &amp;lt;tex&amp;gt; A &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Разбиения упорядочены лексикографически следующим образом. Разбиение &amp;lt;tex&amp;gt;N_n = A_1 \cup A_2 \cup . . . \cup A_k&amp;lt;/tex&amp;gt; лексикографически меньше разбиения &amp;lt;tex&amp;gt;N_n = B_1 \cup B_2 \cup . . . \cup B_l&amp;lt;/tex&amp;gt; если существует такое &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, что &amp;lt;tex&amp;gt;A_1 = B_1, A_2 = B_2, . . . ,A_{i - 1} = B_{i - 1}, A_i &amp;lt; B_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Рассмотрим алгоритм нахождения лексикографически следующего разбиения на подмножества:'''&lt;br /&gt;
*Будем хранить подмножества в списке списков, например, разбиение &amp;lt;tex&amp;gt; \{1, 2, 3\}~ \{4, 5\}&amp;lt;/tex&amp;gt; будет выглядеть так:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3&lt;br /&gt;
|-&lt;br /&gt;
|4||5|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* Будем поддерживать массив &amp;quot;удалённых&amp;quot; элементов {{---}} элементы которые затем нужно будет вернуть в разбиение.&lt;br /&gt;
&lt;br /&gt;
* Двигаясь снизу вверх будем рассматривать подмножества.&lt;br /&gt;
** Если мы можем дописать в текущее подмножество минимальный элемент из удалённых, то мы нашли следующее разбиение и идти дальше вверх не нужно.&lt;br /&gt;
** Если дописать не можем, значит, либо нужно укоротить и заменить какой то элемент в текущем подмножестве, либо перейти к следующему подмножеству. Будем идти справа налево и рассамтривать элементы:&lt;br /&gt;
*** Если мы можем заменить текущий элемент минимальным удалённым {{---}} мы нашли следующее разбиение, завершаем оба прохода. Стоит отметить, что нельзя перезаписывать последний элемент в подмножестве, иначе мы не сможем дописать минимальный хвост после этого подмножества {{---}} в удалённых будет элемент меньше текущего и мы не сможем дописать правильный хвост.&lt;br /&gt;
*** Если заменить не можем, то его нужно удалить.&lt;br /&gt;
* Допишем лексикографически минимальный хвост подмножеств из оставшихся удалённых элементов.&lt;br /&gt;
&lt;br /&gt;
 '''list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;''' nextSetPartition('''list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;''' a):&lt;br /&gt;
   used = '''list&amp;lt;int&amp;gt;'''&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// a {{---}} список, содержащий подмножества&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// used {{---}} список, в котором мы храним удаленные элементы&amp;lt;/font&amp;gt;&lt;br /&gt;
   fl = ''false''&lt;br /&gt;
   '''for''' i = a.size - 1 '''downto''' 0&lt;br /&gt;
     '''if''' (used.size != 0) '''and''' (max(used) &amp;gt; a[i][-1])   &amp;lt;font color=green&amp;gt;// в удалённых есть хотя бы один элемент, который мы можем добавить в конец.&amp;lt;/font&amp;gt;&lt;br /&gt;
       m = '''минимум из''' used '''строго больше''' a[i][-1]&lt;br /&gt;
       a[i].add(m)   &amp;lt;font color=green&amp;gt;//добавляем&amp;lt;/font&amp;gt;&lt;br /&gt;
       used.remove(m)&lt;br /&gt;
       '''break'''&lt;br /&gt;
     '''for''' j = a[i].size - 1 '''downto''' 0&lt;br /&gt;
       '''if''' (used.size != 0) '''and''' (j != 0) '''and''' (max(used) &amp;gt; a[i][j])   &amp;lt;font color=green&amp;gt;//если можем заменить элемент, другим элементом из списка used и он не последний&amp;lt;/font&amp;gt;&lt;br /&gt;
         m = '''минимум из''' used '''строго больше''' a[i][-1]&lt;br /&gt;
         a[i][j] = m   &amp;lt;font color=green&amp;gt;//заменяем&amp;lt;/font&amp;gt;&lt;br /&gt;
         used.remove(m)&lt;br /&gt;
         fl = ''true''&lt;br /&gt;
         '''break'''&lt;br /&gt;
       '''else'''&lt;br /&gt;
         used.add(a[i][-1])&lt;br /&gt;
         a[i].pop()&lt;br /&gt;
         '''if''' a[i].size == 0&lt;br /&gt;
           a.pop()&lt;br /&gt;
      '''if''' fl &lt;br /&gt;
        '''break'''&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;//далее выведем все удалённые, которые не выбрали&amp;lt;/font&amp;gt;&lt;br /&gt;
   sort(used)&lt;br /&gt;
   '''for''' i = 0 '''to''' used.size - 1&lt;br /&gt;
      a.add('''list&amp;lt;int&amp;gt;'''(used[i]))   &amp;lt;font color=green&amp;gt;//добавляем лексикографически минимальных хвост&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''return''' a&lt;br /&gt;
&lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
&lt;br /&gt;
'''Рассмотрим следующее разбиение:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3&lt;br /&gt;
|-&lt;br /&gt;
|4||5|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''1 Шаг:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||&lt;br /&gt;
|-&lt;br /&gt;
|4||style=&amp;quot;background:#FFCC00&amp;quot;|5||||&lt;br /&gt;
|-&lt;br /&gt;
| ||^|| ||Удалили элемент 5.&lt;br /&gt;
|-&lt;br /&gt;
| || || ||used&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2 Шаг:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#FFCC00&amp;quot;|4|| ||||&lt;br /&gt;
|-&lt;br /&gt;
|^|| || ||Удалили элемент 4. Так как он является последним в подмножестве, то мы не можем заменить его на другой.&lt;br /&gt;
|-&lt;br /&gt;
|5|| || ||used&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''3 Шаг:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||style=&amp;quot;background:#FFCC00&amp;quot;|4||&lt;br /&gt;
|-&lt;br /&gt;
| || || ||^||Дополнили первое подмножество элементом 4&lt;br /&gt;
|-&lt;br /&gt;
|5|| || || ||used&lt;br /&gt;
|}  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''4 Шаг:''' &lt;br /&gt;
    &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||4||&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#FFCC00&amp;quot;|5|| || || ||Дописали лексикографически минимальный хвост&lt;br /&gt;
|-&lt;br /&gt;
| || || || ||used&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Irdkwmnsb</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D1%81%D0%BB%D0%B5%D0%B4%D1%83%D1%8E%D1%89%D0%B5%D0%B3%D0%BE_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%B0&amp;diff=75934</id>
		<title>Получение следующего объекта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%BB%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D1%81%D0%BB%D0%B5%D0%B4%D1%83%D1%8E%D1%89%D0%B5%D0%B3%D0%BE_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%B0&amp;diff=75934"/>
				<updated>2021-01-01T17:07:43Z</updated>
		
		<summary type="html">&lt;p&gt;Irdkwmnsb: /* Специализация алгоритма для генерации следующего разбиения на подмножества */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Алгоритм ==&lt;br /&gt;
{{Определение|definition= '''Получение следующего объекта''' {{---}} это нахождение объекта, следующего за данным в [[Лексикографический порядок|лексикографическом порядке]].&lt;br /&gt;
}}&lt;br /&gt;
Объект &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; называется следующим за &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;P &amp;lt; Q&amp;lt;/tex&amp;gt; и не найдется такого &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt;, что &amp;lt;tex&amp;gt;P &amp;lt; R &amp;lt; Q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Отсюда понятен алгоритм:&lt;br /&gt;
* находим суффикс минимальной длины, который можно изменить без изменения префикса текущего объекта &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* к оставшейся части дописываем минимальный возможный элемент (чтобы было выполнено правило &amp;lt;tex&amp;gt;P &amp;lt; Q&amp;lt;/tex&amp;gt;),&lt;br /&gt;
* дописываем минимальный возможный хвост.&lt;br /&gt;
По построению получаем, что &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; {{---}} минимально возможный.&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующего битового вектора ==&lt;br /&gt;
* Находим минимальный суффикс, в котором есть &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, его можно увеличить, не меняя оставшейся части&lt;br /&gt;
* Вместо &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; записываем &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; &lt;br /&gt;
* Дописываем минимально возможный хвост из нулей&lt;br /&gt;
 '''int[]''' nextVector('''int[]''' a): &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} длина вектора&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''while''' (n &amp;gt;= 0) '''and''' (a[n] != 0)&lt;br /&gt;
       a[n] = 0&lt;br /&gt;
       n--&lt;br /&gt;
   '''if''' n == -1&lt;br /&gt;
     '''return''' ''null''&lt;br /&gt;
   a[n] = 1&lt;br /&gt;
   '''return''' a&lt;br /&gt;
Приведённый алгоритм эквивалентен прибавлению единицы к битовому вектору. &lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|0||1||0||1||style=&amp;quot;background:#FFCC00&amp;quot;|1||исходный битовый вектор&lt;br /&gt;
|-&lt;br /&gt;
| || || || ||^|| начинаем идти с конца&lt;br /&gt;
|-&lt;br /&gt;
|0||1||0||style=&amp;quot;background:#FFCC00&amp;quot;|0||style=&amp;quot;background:#FFCC00&amp;quot;|0|| пока элементы равны 1, заменяем их на 0&lt;br /&gt;
|-&lt;br /&gt;
|0||1||style=&amp;quot;background:#FFCC00&amp;quot;|1||0||0|| меняем первый не удовлетворяющий условию цикла элемент на 1&lt;br /&gt;
|-&lt;br /&gt;
|'''0'''||'''1'''||'''1'''||'''0'''||'''0'''||следующий битовый вектор&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующей перестановки ==&lt;br /&gt;
* Двигаясь справа налево, находим элемент, нарушающий убывающую последовательность (в обычном порядке, слева направо, см. пример)&lt;br /&gt;
* Меняем его с минимальным элементом, большим нашего, стоящим правее&lt;br /&gt;
* Перевернем правую часть&lt;br /&gt;
&lt;br /&gt;
 '''int[]''' nextPermutation('''int[]''' a): &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} длина перестановки&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''for''' i = n - 2 '''downto''' 0&lt;br /&gt;
     '''if''' a[i] &amp;lt; a[i + 1]&lt;br /&gt;
       min = i + 1;&lt;br /&gt;
       '''for''' j = i + 1 '''to''' n - 1&lt;br /&gt;
         '''if''' (a[j] &amp;lt; a[min]) '''and''' (a[j] &amp;gt; a[i])&lt;br /&gt;
           min = j&lt;br /&gt;
       swap(a[i], a[min])&lt;br /&gt;
       reverse(a, i + 1, n - 1)&lt;br /&gt;
       '''return''' a&lt;br /&gt;
   '''return''' ''null'' &lt;br /&gt;
&lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||3||style=&amp;quot;background:#FFCC00&amp;quot;|2||5||style=&amp;quot;background:#FFCC00&amp;quot;|4||исходная перестановка&lt;br /&gt;
|-&lt;br /&gt;
| || ||^|| || ||находим элемент, нарушающий убывающую последовательность&lt;br /&gt;
|-&lt;br /&gt;
| || || || ||^||минимальный элемент больше нашего&lt;br /&gt;
|-&lt;br /&gt;
|1||3||style=&amp;quot;background:#FFCC00&amp;quot;|4||5||style=&amp;quot;background:#FFCC00&amp;quot;|2||меняем их местами&lt;br /&gt;
|-&lt;br /&gt;
|1||3||4||style=&amp;quot;background:#FFCC00&amp;quot;|2||style=&amp;quot;background:#FFCC00&amp;quot;|5||разворачивам правую часть&lt;br /&gt;
|-&lt;br /&gt;
|'''1'''||'''3'''||'''4'''||'''2'''||'''5'''||следующая перестановка&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующей мультиперестановки ==&lt;br /&gt;
* Двигаясь справа налево, находим элемент, нарушающий убывающую последовательность (в обычном порядке, слева направо, см. пример).&lt;br /&gt;
* Меняем его с минимальным элементом, большим нашего, стоящим правее.&lt;br /&gt;
* Переворачиваем правую часть.&lt;br /&gt;
 '''int[]''' nextMultiperm('''int[]''' b):  &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} длина мультиперестановки&amp;lt;/font&amp;gt;&lt;br /&gt;
     i = n - 2&lt;br /&gt;
     '''while''' (i &amp;gt;= 0) '''and''' (b[i] &amp;gt;= b[i + 1]) &lt;br /&gt;
       i--&lt;br /&gt;
     '''if''' i &amp;gt;= 0 &lt;br /&gt;
       j = i + 1&lt;br /&gt;
       '''while''' (j &amp;lt; n - 1) '''and''' (b[j + 1] &amp;gt; b[i]) &lt;br /&gt;
         j++&lt;br /&gt;
       swap(b[i] , b[j])&lt;br /&gt;
       reverse(b, i + 1, n - 1)&lt;br /&gt;
       '''return''' b&lt;br /&gt;
     '''else'''&lt;br /&gt;
       '''return''' ''null''&lt;br /&gt;
&lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||1||style=&amp;quot;background:#FFCC00&amp;quot;|2||style=&amp;quot;background:#FFCC00&amp;quot;|3||Исходная перестановка.&lt;br /&gt;
|-&lt;br /&gt;
| || || || ||^|| ||Находим элемент, нарушающий убывающую последовательность.&lt;br /&gt;
|-&lt;br /&gt;
| || || || || ||^||Минимальный элемент больше нашего.&lt;br /&gt;
|-&lt;br /&gt;
|1||2||3||1||style=&amp;quot;background:#FFCC00&amp;quot;|3||style=&amp;quot;background:#FFCC00&amp;quot;|2||Меняем их местами.&lt;br /&gt;
|-&lt;br /&gt;
|'''1'''||'''2'''||'''3'''||'''1'''||'''3'''||'''2'''||Следующая мультиперестановка.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующего сочетания ==&lt;br /&gt;
&lt;br /&gt;
* Добавим в конец массива с сочетанием &amp;lt;tex&amp;gt;N+1&amp;lt;/tex&amp;gt; – максимальный элемент.&lt;br /&gt;
* Пойдём справа налево. Будем искать номер элемента, который отличается от предыдущего на &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; и больше.&lt;br /&gt;
* Увеличим найденный элемент на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, и допишем в конец минимально возможный хвост, если такого элемента нет – на вход было дано последнее сочетание.&lt;br /&gt;
 '''int[]''' nextChoose('''int[]''' a, '''int''' n, '''int''' k): &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;n,k &amp;lt;/tex&amp;gt; {{---}} параметры сочетания&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''for''' i = 0 '''to''' k - 1 &lt;br /&gt;
     b[i] = a[i]&lt;br /&gt;
   b[k] = n + 1&lt;br /&gt;
   i = k - 1&lt;br /&gt;
   '''while''' (i &amp;gt;= 0) '''and''' (b[i + 1] - b[i] &amp;lt; 2) &lt;br /&gt;
     i--&lt;br /&gt;
   '''if''' i &amp;gt;= 0 &lt;br /&gt;
      b[i]++&lt;br /&gt;
      '''for''' j = i + 1 '''to''' k - 1 &lt;br /&gt;
        b[j] = b[j - 1] + 1&lt;br /&gt;
      '''for''' i = 0 '''to''' k - 1 &lt;br /&gt;
        a[i] = b[i]&lt;br /&gt;
      '''return''' a&lt;br /&gt;
   '''else'''&lt;br /&gt;
     '''return''' ''null''&lt;br /&gt;
&lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||5||6||style=&amp;quot;background:#FFCC00&amp;quot;|'''7'''||Дописываем 7 в конец сочетания.&lt;br /&gt;
|-&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|2||5||6||'''7'''||&lt;br /&gt;
|-&lt;br /&gt;
| ||^|| || || ||Находим элемент i, a[i + 1] - a[ i ] &amp;gt;= 2&lt;br /&gt;
|-&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|3||5||6||'''7'''||Увеличиваем его на 1.&lt;br /&gt;
|-&lt;br /&gt;
|1||3||style=&amp;quot;background:#FFCC00&amp;quot;|4||style=&amp;quot;background:#FFCC00&amp;quot;|5||style=&amp;quot;background:#FFCC00&amp;quot;|'''6'''||Дописываем минимальный хвост.&lt;br /&gt;
|-&lt;br /&gt;
|'''1'''||'''3'''||'''4'''||'''5'''||''' '''||Следующее сочетание.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующего разбиения на слагаемые ==&lt;br /&gt;
Рассматриваемый алгоритм находит следующее [[комбинаторные объекты|разбиение на слагаемые]], при этом разбиение упорядоченно по возрастанию.&lt;br /&gt;
* Увеличим предпоследнее слагаемое на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, уменьшим последнее слагаемое на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
** Если предпоследнее слагаемое стало больше последнего, то увеличиваем предпоследнее слагаемое на величину последнего.&lt;br /&gt;
** Если предпоследнее слагаемое умноженное на 2 меньше последнего, то разбиваем последнее слагаемое &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; на два слагаемых &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; таких, что &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; равно предпоследнему слагаемому, а &amp;lt;tex&amp;gt;b = s - a&amp;lt;/tex&amp;gt;. Повторяем этот процесс, пока разбиение остается корректным, то есть предпоследнее слагаемое хотя бы в два раза меньше последнего.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; {{---}} список, содержащий разбиение данного числа &amp;lt;tex&amp;gt;b.size&amp;lt;/tex&amp;gt;{{---}} его размер &amp;lt;/font&amp;gt;&lt;br /&gt;
 '''list&amp;lt;int&amp;gt;'''  nextPartition('''list&amp;lt;int&amp;gt;''' b): &lt;br /&gt;
    b[b.size - 1]--&lt;br /&gt;
    b[b.size - 2]++&lt;br /&gt;
    '''if''' b[b.size - 2] &amp;gt; b[b.size - 1] &lt;br /&gt;
       b[b.size - 2] += b[b.size - 1]&lt;br /&gt;
       b.remove(b.size - 1)&lt;br /&gt;
    '''else'''&lt;br /&gt;
      '''while''' b[b.size - 2] * 2 &amp;lt;= b[b.size - 1] &lt;br /&gt;
        b.add(b[b.size - 1] - b[b.size - 2])&lt;br /&gt;
        b[b.size - 2] = b[b.size - 3]&lt;br /&gt;
    '''return''' b&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|1||style=&amp;quot;background:#FFCC00&amp;quot;|7|| || ||Прибавим 1 + 1, вычтем 7 - 1.&lt;br /&gt;
|-&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|2||style=&amp;quot;background:#FFCC00&amp;quot;|6|| || ||Проверяем: 2 &amp;lt; 6, значит разбиваем 6 пока оно не станет меньше 4&lt;br /&gt;
|-&lt;br /&gt;
|1||2||style=&amp;quot;background:#FFCC00&amp;quot;|2||style=&amp;quot;background:#FFCC00&amp;quot;|4|| ||&lt;br /&gt;
|-&lt;br /&gt;
|1||2||2||style=&amp;quot;background:#FFCC00&amp;quot;|2||style=&amp;quot;background:#FFCC00&amp;quot;|2||&lt;br /&gt;
|-&lt;br /&gt;
|'''1'''||'''2'''||'''2'''||'''2'''||'''2'''||Следующее разбиение на слагаемые числа 9.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|4||style=&amp;quot;background:#FFCC00&amp;quot;|5||Прибавим 4 + 1, вычтем 5 - 1.&lt;br /&gt;
|-&lt;br /&gt;
|1||style=&amp;quot;background:#FFCC00&amp;quot;|5||style=&amp;quot;background:#FFCC00&amp;quot;|4||Проверяем: 5 &amp;gt; 4, значит прибавим к 5 + 4.&lt;br /&gt;
|-&lt;br /&gt;
|1||9||style=&amp;quot;background:#FFCC00&amp;quot;|4||Удалим последний элемент.&lt;br /&gt;
|-&lt;br /&gt;
|'''1'''||'''9'''||||Следующее разбиение на слагаемые числа 10.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации следующего разбиения на подмножества ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим множество первых n натуральных чисел:&amp;lt;tex&amp;gt;N_n = \{1, 2, ..., n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Упорядочим все разбиения на множества &amp;lt;tex&amp;gt;N_n&amp;lt;/tex&amp;gt; лексикографически. Для этого, во-первых, в каждом разбиении упорядочим множества лексикографически. Будем говорить, что подмножество &amp;lt;tex&amp;gt; A \subset N_n &amp;lt;/tex&amp;gt; лексикографически меньше подмножества &amp;lt;tex&amp;gt; B \subset N_n &amp;lt;/tex&amp;gt; , если верно одно из следующих условий:&lt;br /&gt;
&lt;br /&gt;
*существует &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; такое, что &amp;lt;tex&amp;gt;i \in A&amp;lt;/tex&amp;gt; , &amp;lt;tex&amp;gt;i \notin B&amp;lt;/tex&amp;gt;, для всех &amp;lt;tex&amp;gt;j &amp;lt; i: j \in A&amp;lt;/tex&amp;gt; если и только если &amp;lt;tex&amp;gt;j \in B&amp;lt;/tex&amp;gt; , и существует &amp;lt;tex&amp;gt;k &amp;gt; i&amp;lt;/tex&amp;gt; такое что &amp;lt;tex&amp;gt;k \in B&amp;lt;/tex&amp;gt;;&lt;br /&gt;
* &amp;lt;tex&amp;gt; A \subset B &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;i &amp;lt; j&amp;lt;/tex&amp;gt; для всех &amp;lt;tex&amp;gt;i \in A&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j \in B&amp;lt;/tex&amp;gt; \ &amp;lt;tex&amp;gt; A &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Разбиения упорядочены лексикографически следующим образом. Разбиение &amp;lt;tex&amp;gt;N_n = A_1 \cup A_2 \cup . . . \cup A_k&amp;lt;/tex&amp;gt; лексикографически меньше разбиения &amp;lt;tex&amp;gt;N_n = B_1 \cup B_2 \cup . . . \cup B_l&amp;lt;/tex&amp;gt; если существует такое &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, что &amp;lt;tex&amp;gt;A_1 = B_1, A_2 = B_2, . . . ,A_{i - 1} = B_{i - 1}, A_i &amp;lt; B_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Рассмотрим алгоритм нахождения лексикографически следующего разбиения на подмножества:'''&lt;br /&gt;
*Будем хранить подмножества в списке списков, например, разбиение &amp;lt;tex&amp;gt; \{1, 2, 3\}~ \{4, 5\}&amp;lt;/tex&amp;gt; будет выглядеть так:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3&lt;br /&gt;
|-&lt;br /&gt;
|4||5|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* Будем поддерживать массив &amp;quot;удалённых&amp;quot; элементов {{---}} элементы которые затем нужно будет вернуть в разбиение.&lt;br /&gt;
&lt;br /&gt;
* Двигаясь снизу вверх будем рассматривать подмножества.&lt;br /&gt;
** Если мы можем дописать в текущее подмножество минимальный элемент из удалённых, то мы нашли следующее разбиение и идти дальше вверх не нужно.&lt;br /&gt;
** Если дописать не можем, значит, либо нужно укоротить и заменить какой то элемент в текущем подмножестве, либо перейти к следующему подмножеству. Будем идти справа налево и рассамтривать элементы:&lt;br /&gt;
*** Если мы можем заменить текущий элемент минимальным удалённым {{---}} мы нашли следующее разбиение, завершаем оба прохода. Стоит отметить, что нельзя перезаписывать последний элемент в подмножестве, иначе мы не сможем дописать минимальный хвост после этого подмножества {{---}} в удалённых будет элемент меньше текущего и мы не сможем дописать правильный хвост.&lt;br /&gt;
*** Если заменить не можем, то его нужно удалить.&lt;br /&gt;
* Допишем лексикографически минимальный хвост подмножеств из оставшихся удалённых элементов.&lt;br /&gt;
&lt;br /&gt;
 '''list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;''' nextSetPartition('''list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;''' a):&lt;br /&gt;
   used = '''list&amp;lt;int&amp;gt;'''&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// a {{---}} список, содержащий подмножества&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// used {{---}} список, в котором мы храним удаленные элементы&amp;lt;/font&amp;gt;&lt;br /&gt;
   fl = ''false''&lt;br /&gt;
   '''for''' i = a.size - 1 '''downto''' 0&lt;br /&gt;
     '''if''' (used.size != 0) '''and''' (max(used) &amp;gt; a[i][-1])   &amp;lt;font color=green&amp;gt;// в удалённых есть хотя бы один элемент, который мы можем добавить в конец.&amp;lt;/font&amp;gt;&lt;br /&gt;
       m = '''минимум из''' used '''строго больше''' a[i][-1]&lt;br /&gt;
       a[i].add(m)   &amp;lt;font color=green&amp;gt;//добавляем&amp;lt;/font&amp;gt;&lt;br /&gt;
       used.remove(m)&lt;br /&gt;
       '''break'''&lt;br /&gt;
     '''for''' j = a[i].size - 1 '''downto''' 0&lt;br /&gt;
       '''if''' (used.size != 0) '''and''' (j != 0) '''and''' (max(used) &amp;gt; a[i][j])   &amp;lt;font color=green&amp;gt;//если можем заменить элемент, другим элементом из списка used и он не последний&amp;lt;/font&amp;gt;&lt;br /&gt;
         m = '''минимум из''' used '''строго больше''' a[i][-1]&lt;br /&gt;
         a[i][j] = m   &amp;lt;font color=green&amp;gt;//заменяем&amp;lt;/font&amp;gt;&lt;br /&gt;
         used.remove(m)&lt;br /&gt;
         fl = ''true''&lt;br /&gt;
         '''break'''&lt;br /&gt;
       '''else'''&lt;br /&gt;
         used.add(a[i][-1])&lt;br /&gt;
         a[i].pop()&lt;br /&gt;
         '''if''' a[i].size == 0&lt;br /&gt;
           a.pop()&lt;br /&gt;
      '''if''' fl &lt;br /&gt;
        '''break'''&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;//далее выведем все удалённые, которые не выбрали&amp;lt;/font&amp;gt;&lt;br /&gt;
   sort(used)&lt;br /&gt;
   '''for''' i = 0 '''to''' used.size - 1&lt;br /&gt;
      a.add('''list&amp;lt;int&amp;gt;'''(used[i]))   &amp;lt;font color=green&amp;gt;//добавляем лексикографически минимальных хвост&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''return''' a&lt;br /&gt;
&lt;br /&gt;
=== Пример работы ===&lt;br /&gt;
&lt;br /&gt;
'''Рассмотрим следующее разбиение:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3&lt;br /&gt;
|-&lt;br /&gt;
|4||5|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''1 Шаг:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||&lt;br /&gt;
|-&lt;br /&gt;
|4||style=&amp;quot;background:#FFCC00&amp;quot;|5||||&lt;br /&gt;
|-&lt;br /&gt;
| ||^|| ||Удалили элемент 5.&lt;br /&gt;
|-&lt;br /&gt;
| || || ||used&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2 Шаг:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#FFCC00&amp;quot;|4|| ||||&lt;br /&gt;
|-&lt;br /&gt;
|^|| || ||Удалили элемент 4. Так как он является последним в подмножестве, то мы не можем заменить его на другой.&lt;br /&gt;
|-&lt;br /&gt;
|5|| || ||used&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''3 Шаг:'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||style=&amp;quot;background:#FFCC00&amp;quot;|4||&lt;br /&gt;
|-&lt;br /&gt;
| || || ||^||Дополнили первое подмножество элементом 4&lt;br /&gt;
|-&lt;br /&gt;
|5|| || || ||used&lt;br /&gt;
|}  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''4 Шаг:''' &lt;br /&gt;
    &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border = 1&lt;br /&gt;
|1||2||3||4||&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#FFCC00&amp;quot;|5|| || || ||Дописали лексикографически минимальный хвост&lt;br /&gt;
|-&lt;br /&gt;
| || || || ||used&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== См.также ==&lt;br /&gt;
* [[Получение предыдущего объекта]]&lt;br /&gt;
* [[Получение объекта по номеру]]&lt;br /&gt;
* [[Получение номера по объекту]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
&lt;br /&gt;
* [http://rain.ifmo.ru/cat/view.php/vis/combinations/permutations-2000 Визуализатор перестановок]&lt;br /&gt;
* [http://cppalgo.blogspot.com/2011/02/episode-2.html Пример компактного кода для перестановок (С++)]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Комбинаторика]]&lt;/div&gt;</summary>
		<author><name>Irdkwmnsb</name></author>	</entry>

	</feed>