<?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=91.122.22.64&amp;*</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=91.122.22.64&amp;*"/>
		<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/91.122.22.64"/>
		<updated>2026-05-19T18:00:44Z</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=35119</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=35119"/>
				<updated>2014-01-04T23:04:18Z</updated>
		
		<summary type="html">&lt;p&gt;91.122.22.64: /* Специализация алгоритма для генерации следующего разбиения на подмножества */&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;
== Специализация алгоритма для генерации следующего [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 битового вектора] ==&lt;br /&gt;
* Находим минимальный суффикс, в котором есть 0, его можно увеличить, не меняя оставшейся части&lt;br /&gt;
* Вместо 0 записываем 1 &lt;br /&gt;
* Дописываем минимально возможный хвост из нулей&lt;br /&gt;
     '''function''' nextVector(a:array[1..n] of byte):array[1..n] of byte; // n - длина вектора&lt;br /&gt;
      '''for''' i = n '''downto''' 1&lt;br /&gt;
       '''if''' a[i] == 0&lt;br /&gt;
        a[i] = 1&lt;br /&gt;
        '''for''' j = i + 1 to n&lt;br /&gt;
         a[j] = 0&lt;br /&gt;
         '''break'''&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||style=&amp;quot;background:#FFCC00&amp;quot;|0||1||1||исходный битовый вектор&lt;br /&gt;
|-&lt;br /&gt;
| || ||^|| || ||находим элемент 0 (самый правый)&lt;br /&gt;
|-&lt;br /&gt;
|0||1||style=&amp;quot;background:#FFCC00&amp;quot;|1||1||1||меняем его на 1&lt;br /&gt;
|-&lt;br /&gt;
|0||1||1||style=&amp;quot;background:#FFCC00&amp;quot;|0||style=&amp;quot;background:#FFCC00&amp;quot;|0||меняем элементы правее на нули&lt;br /&gt;
|-&lt;br /&gt;
|'''0'''||'''1'''||'''1'''||'''0'''||'''0'''||следующий битовый вектор&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 следующей перестановки] ==&lt;br /&gt;
* Двигаясь справа налево, находим элемент, нарушающий убывающую последовательность (в обычном порядке, слева направо, см. пример)&lt;br /&gt;
* Меняем его с минимальным элементом, большим нашего, стоящим правее&lt;br /&gt;
* Перевернем правую часть&lt;br /&gt;
&lt;br /&gt;
  '''function''' nextPermutation(a:array[1..n] of integer):array[1..n] of integer; // n - длина перестановки&lt;br /&gt;
   '''for''' i = n - 1 '''downto''' 1&lt;br /&gt;
       '''if''' a[i] &amp;lt; a[i + 1]&lt;br /&gt;
           '''for''' j = i + 1 '''to''' n&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[j])&lt;br /&gt;
           reverse(a[i + 1]..a[n])&lt;br /&gt;
           '''break'''&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;
|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;
== Специализация алгоритма для генерации следующей [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 мультиперестановки] ==&lt;br /&gt;
* Двигаясь справа налево, находим элемент, нарушающий убывающую последовательность (в обычном порядке, слева направо, см. пример).&lt;br /&gt;
* Меняем его с минимальным элементом, большим нашего, стоящим правее.&lt;br /&gt;
* Переворачиваем правую часть.&lt;br /&gt;
 '''function''' nextMultiperm(var b:array[1..N] of integer): array[1..N] of integer;&lt;br /&gt;
   '''var''' i , j : '''integer''';&lt;br /&gt;
   '''begin'''&lt;br /&gt;
    i := N - 1;&lt;br /&gt;
    '''while''' (i &amp;gt; 0) '''and''' (b[i] &amp;gt;= b[i + 1]) '''do'''&lt;br /&gt;
     dec(i);&lt;br /&gt;
    '''if''' i &amp;gt; 0 '''then'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
       j := i + 1;&lt;br /&gt;
       '''while''' (j &amp;lt; N) '''and''' (b[j + 1] &amp;gt; b[i]) '''do'''&lt;br /&gt;
         inc(j);&lt;br /&gt;
       swap(b[i] , b[j]);&lt;br /&gt;
       '''for''' j := i + 1 '''to''' (N + i) '''div''' 2 '''do'''&lt;br /&gt;
         swap(b[j], b[N - j + i + 1]);&lt;br /&gt;
       return(b[1..N]);&lt;br /&gt;
     '''end'''&lt;br /&gt;
    '''else'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
       return(null);&lt;br /&gt;
     '''end;'''&lt;br /&gt;
   '''end;'''&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;
== Специализация алгоритма для генерации [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 следующего сочетания] ==&lt;br /&gt;
&lt;br /&gt;
* Добавим в конец массива с сочетанием N+1 – максимальный элемент.&lt;br /&gt;
* Пойдём справа налево. Будем искать номер элемента, который отличается от предыдущего на 2.&lt;br /&gt;
* Увеличим найденный элемент на 1, и допишем в конец минимально возможный хвост, если такого элемента нет – на вход было дано последнее сочетание.&lt;br /&gt;
 '''function''' nextChoose(var a:array[1..k] of integer): array[1..k] of integer; // n,k - параметры сочетания.&lt;br /&gt;
  '''var''' &lt;br /&gt;
   i,j : '''integer;'''&lt;br /&gt;
   b:array[1..k+1] of '''integer;'''&lt;br /&gt;
  '''begin'''&lt;br /&gt;
   '''for''' i := 1 '''to''' k '''do'''&lt;br /&gt;
    b[i]:=a[i];&lt;br /&gt;
   b[k + 1] := n + 1;&lt;br /&gt;
   i := n;&lt;br /&gt;
   '''while''' (i &amp;gt; 0) '''and''' ((b[i + 1] - b[i]) &amp;lt; 2) '''do'''&lt;br /&gt;
     i := i - 1;&lt;br /&gt;
   '''if''' i &amp;gt; 0 '''then'''&lt;br /&gt;
    '''begin'''&lt;br /&gt;
      b[i] := b[i] + 1;&lt;br /&gt;
      '''for''' j := i + 1 '''to''' k '''do'''&lt;br /&gt;
       b[j] := b[j - 1] + 1;&lt;br /&gt;
      '''for''' i := 1 '''to''' k '''do'''&lt;br /&gt;
       a[i] := b[i];&lt;br /&gt;
      return(a[1..k]);&lt;br /&gt;
    '''end'''&lt;br /&gt;
   '''else'''&lt;br /&gt;
    return(null);&lt;br /&gt;
  '''end;'''&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;
== Специализация алгоритма для генерации следующего [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 разбиения на слагаемые] ==&lt;br /&gt;
Рассматриваемый алгоритм находит следующее разбиение на слагаемые, при этом разбиение упорядоченно по возрастанию.&lt;br /&gt;
* Увеличим предпоследнее слагаемое на 1, уменьшим последнее слагаемое на 1.&lt;br /&gt;
** Если предпоследнее слагаемое стало больше последнего, то увеличиваем предпоследнее слагаемое на величину последнего.&lt;br /&gt;
** Если предпоследнее слагаемое меньше последнего, то разбиваем последнее слагаемое &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;
 // b – список, содержащий разбиение данного числа, length – его размер.&lt;br /&gt;
 '''function''' nextPartition(var b: list&amp;lt;int&amp;gt;): list&amp;lt;int&amp;gt;;&lt;br /&gt;
  '''var''' i : '''integer;'''&lt;br /&gt;
   '''begin'''   &lt;br /&gt;
    b[b.size] := b[b.size] - 1;&lt;br /&gt;
    b[b.size - 1] := b[b.size - 1] + 1;&lt;br /&gt;
    '''if''' b[b.size - 1] &amp;gt; b[b.size] '''then'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
       b[b.size - 1] := b[b.size - 1] + b[b.size];&lt;br /&gt;
       b.pop();&lt;br /&gt;
     '''end'''&lt;br /&gt;
    '''else'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
      '''while''' b[b.size - 1] * 2 &amp;lt;= b[b.size] '''do'''&lt;br /&gt;
       '''begin'''&lt;br /&gt;
        b.add(b[b.size] - b[b.size - 1]);&lt;br /&gt;
        b[b.size - 1] := b[b.size - 2];&lt;br /&gt;
       '''end;'''&lt;br /&gt;
     '''end;'''&lt;br /&gt;
    '''return''' b;&lt;br /&gt;
   '''end;'''&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 пока оно не станет &amp;lt;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;
== Специализация алгоритма для генерации следующего [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 разбиения на подмножества] ==&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;
** Заменить рассматриваемый элемент уже удаленным. Из всех подходящих элементов выбираем минимальный. '''Важное замечание''': мы не можем заменить 1ый элемент подмножества, мы можем только удалить его.&lt;br /&gt;
** Дополнить рассматриваемое подмножество уже удаленным элементом. Из всех подходящих элементов выбираем минимальный.&lt;br /&gt;
* Допишем лексикографически минимальный хвост подмножеств из оставшихся элементов.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 '''function''' nextSetPartition(a:list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;):list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;;&lt;br /&gt;
  // a - список, содержащий подмножества&lt;br /&gt;
  // used - список, в котором мы храним удаленные элементы&lt;br /&gt;
  used = list&amp;lt;int&amp;gt;();&lt;br /&gt;
  fl = ''false''&lt;br /&gt;
  '''for''' i = a.size '''downto''' 1&lt;br /&gt;
      '''if''' (used.size &amp;lt;&amp;gt; 0) and (used[used.size] &amp;gt; a[i][a[i].size]) '''then'''   //если можем добавить в конец подмножества элемент из used&lt;br /&gt;
          a[i].add(used[used.size]);   //добавляем&lt;br /&gt;
          used.remove(used.size);&lt;br /&gt;
          '''break'''&lt;br /&gt;
      '''for''' j = a[i].size '''downto''' 1&lt;br /&gt;
          '''if''' (used.size &amp;lt;&amp;gt; 0) and (j &amp;lt;&amp;gt; 1) and (used[used.size] &amp;gt; a[i][j]) '''then'''   //если можем заменить элемент, другим элементом из списка used &lt;br /&gt;
             a[i][j] = used[used.size];   //заменяем&lt;br /&gt;
             fl = ''true''&lt;br /&gt;
             '''break'''&lt;br /&gt;
      '''if''' (fl) '''break'''&lt;br /&gt;
      used.add(a[i][j]);   // добавляем в used j элемент i-го подмножества  &lt;br /&gt;
      a[i].remove(j);   // удаляем j элемент i-го подмножества&lt;br /&gt;
  // далее выведем все получившиеся подмножества&lt;br /&gt;
  sort(used)&lt;br /&gt;
  '''for''' i = 1 '''to''' used.size&lt;br /&gt;
     a.add(list&amp;lt;int&amp;gt;(used[i]));        // добавляем лексикографически минимальных хвост&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;
* [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>91.122.22.64</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=35117</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=35117"/>
				<updated>2014-01-04T23:00:40Z</updated>
		
		<summary type="html">&lt;p&gt;91.122.22.64: /* Специализация алгоритма для генерации следующего разбиения на подмножества */&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;
== Специализация алгоритма для генерации следующего [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 битового вектора] ==&lt;br /&gt;
* Находим минимальный суффикс, в котором есть 0, его можно увеличить, не меняя оставшейся части&lt;br /&gt;
* Вместо 0 записываем 1 &lt;br /&gt;
* Дописываем минимально возможный хвост из нулей&lt;br /&gt;
     '''function''' nextVector(a:array[1..n] of byte):array[1..n] of byte; // n - длина вектора&lt;br /&gt;
      '''for''' i = n '''downto''' 1&lt;br /&gt;
       '''if''' a[i] == 0&lt;br /&gt;
        a[i] = 1&lt;br /&gt;
        '''for''' j = i + 1 to n&lt;br /&gt;
         a[j] = 0&lt;br /&gt;
         '''break'''&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||style=&amp;quot;background:#FFCC00&amp;quot;|0||1||1||исходный битовый вектор&lt;br /&gt;
|-&lt;br /&gt;
| || ||^|| || ||находим элемент 0 (самый правый)&lt;br /&gt;
|-&lt;br /&gt;
|0||1||style=&amp;quot;background:#FFCC00&amp;quot;|1||1||1||меняем его на 1&lt;br /&gt;
|-&lt;br /&gt;
|0||1||1||style=&amp;quot;background:#FFCC00&amp;quot;|0||style=&amp;quot;background:#FFCC00&amp;quot;|0||меняем элементы правее на нули&lt;br /&gt;
|-&lt;br /&gt;
|'''0'''||'''1'''||'''1'''||'''0'''||'''0'''||следующий битовый вектор&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 следующей перестановки] ==&lt;br /&gt;
* Двигаясь справа налево, находим элемент, нарушающий убывающую последовательность (в обычном порядке, слева направо, см. пример)&lt;br /&gt;
* Меняем его с минимальным элементом, большим нашего, стоящим правее&lt;br /&gt;
* Перевернем правую часть&lt;br /&gt;
&lt;br /&gt;
  '''function''' nextPermutation(a:array[1..n] of integer):array[1..n] of integer; // n - длина перестановки&lt;br /&gt;
   '''for''' i = n - 1 '''downto''' 1&lt;br /&gt;
       '''if''' a[i] &amp;lt; a[i + 1]&lt;br /&gt;
           '''for''' j = i + 1 '''to''' n&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[j])&lt;br /&gt;
           reverse(a[i + 1]..a[n])&lt;br /&gt;
           '''break'''&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;
|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;
== Специализация алгоритма для генерации следующей [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 мультиперестановки] ==&lt;br /&gt;
* Двигаясь справа налево, находим элемент, нарушающий убывающую последовательность (в обычном порядке, слева направо, см. пример).&lt;br /&gt;
* Меняем его с минимальным элементом, большим нашего, стоящим правее.&lt;br /&gt;
* Переворачиваем правую часть.&lt;br /&gt;
 '''function''' nextMultiperm(var b:array[1..N] of integer): array[1..N] of integer;&lt;br /&gt;
   '''var''' i , j : '''integer''';&lt;br /&gt;
   '''begin'''&lt;br /&gt;
    i := N - 1;&lt;br /&gt;
    '''while''' (i &amp;gt; 0) '''and''' (b[i] &amp;gt;= b[i + 1]) '''do'''&lt;br /&gt;
     dec(i);&lt;br /&gt;
    '''if''' i &amp;gt; 0 '''then'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
       j := i + 1;&lt;br /&gt;
       '''while''' (j &amp;lt; N) '''and''' (b[j + 1] &amp;gt; b[i]) '''do'''&lt;br /&gt;
         inc(j);&lt;br /&gt;
       swap(b[i] , b[j]);&lt;br /&gt;
       '''for''' j := i + 1 '''to''' (N + i) '''div''' 2 '''do'''&lt;br /&gt;
         swap(b[j], b[N - j + i + 1]);&lt;br /&gt;
       return(b[1..N]);&lt;br /&gt;
     '''end'''&lt;br /&gt;
    '''else'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
       return(null);&lt;br /&gt;
     '''end;'''&lt;br /&gt;
   '''end;'''&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;
== Специализация алгоритма для генерации [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 следующего сочетания] ==&lt;br /&gt;
&lt;br /&gt;
* Добавим в конец массива с сочетанием N+1 – максимальный элемент.&lt;br /&gt;
* Пойдём справа налево. Будем искать номер элемента, который отличается от предыдущего на 2.&lt;br /&gt;
* Увеличим найденный элемент на 1, и допишем в конец минимально возможный хвост, если такого элемента нет – на вход было дано последнее сочетание.&lt;br /&gt;
 '''function''' nextChoose(var a:array[1..k] of integer): array[1..k] of integer; // n,k - параметры сочетания.&lt;br /&gt;
  '''var''' &lt;br /&gt;
   i,j : '''integer;'''&lt;br /&gt;
   b:array[1..k+1] of '''integer;'''&lt;br /&gt;
  '''begin'''&lt;br /&gt;
   '''for''' i := 1 '''to''' k '''do'''&lt;br /&gt;
    b[i]:=a[i];&lt;br /&gt;
   b[k + 1] := n + 1;&lt;br /&gt;
   i := n;&lt;br /&gt;
   '''while''' (i &amp;gt; 0) '''and''' ((b[i + 1] - b[i]) &amp;lt; 2) '''do'''&lt;br /&gt;
     i := i - 1;&lt;br /&gt;
   '''if''' i &amp;gt; 0 '''then'''&lt;br /&gt;
    '''begin'''&lt;br /&gt;
      b[i] := b[i] + 1;&lt;br /&gt;
      '''for''' j := i + 1 '''to''' k '''do'''&lt;br /&gt;
       b[j] := b[j - 1] + 1;&lt;br /&gt;
      '''for''' i := 1 '''to''' k '''do'''&lt;br /&gt;
       a[i] := b[i];&lt;br /&gt;
      return(a[1..k]);&lt;br /&gt;
    '''end'''&lt;br /&gt;
   '''else'''&lt;br /&gt;
    return(null);&lt;br /&gt;
  '''end;'''&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;
== Специализация алгоритма для генерации следующего [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 разбиения на слагаемые] ==&lt;br /&gt;
Рассматриваемый алгоритм находит следующее разбиение на слагаемые, при этом разбиение упорядоченно по возрастанию.&lt;br /&gt;
* Увеличим предпоследнее слагаемое на 1, уменьшим последнее слагаемое на 1.&lt;br /&gt;
** Если предпоследнее слагаемое стало больше последнего, то увеличиваем предпоследнее слагаемое на величину последнего.&lt;br /&gt;
** Если предпоследнее слагаемое меньше последнего, то разбиваем последнее слагаемое &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;
 // b – список, содержащий разбиение данного числа, length – его размер.&lt;br /&gt;
 '''function''' nextPartition(var b: list&amp;lt;int&amp;gt;): list&amp;lt;int&amp;gt;;&lt;br /&gt;
  '''var''' i : '''integer;'''&lt;br /&gt;
   '''begin'''   &lt;br /&gt;
    b[b.size] := b[b.size] - 1;&lt;br /&gt;
    b[b.size - 1] := b[b.size - 1] + 1;&lt;br /&gt;
    '''if''' b[b.size - 1] &amp;gt; b[b.size] '''then'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
       b[b.size - 1] := b[b.size - 1] + b[b.size];&lt;br /&gt;
       b.pop();&lt;br /&gt;
     '''end'''&lt;br /&gt;
    '''else'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
      '''while''' b[b.size - 1] * 2 &amp;lt;= b[b.size] '''do'''&lt;br /&gt;
       '''begin'''&lt;br /&gt;
        b.add(b[b.size] - b[b.size - 1]);&lt;br /&gt;
        b[b.size - 1] := b[b.size - 2];&lt;br /&gt;
       '''end;'''&lt;br /&gt;
     '''end;'''&lt;br /&gt;
    '''return''' b;&lt;br /&gt;
   '''end;'''&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 пока оно не станет &amp;lt;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;
== Специализация алгоритма для генерации следующего [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 разбиения на подмножества] ==&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;
** Заменить рассматриваемый элемент уже удаленным. Из всех подходящих элементов выбираем минимальный. '''Важное замечание''': мы не можем заменить 1ый элемент подмножества, мы можем только удалить его.&lt;br /&gt;
** Дополнить рассматриваемое подмножество уже удаленным элементом. Из всех подходящих элементов выбираем минимальный.&lt;br /&gt;
* Допишем лексикографически минимальный хвост подмножеств из оставшихся элементов.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 '''function''' nextSetPartition(a:list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;):list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;;&lt;br /&gt;
  // a - список, содержащий подмножества&lt;br /&gt;
  // used - список, в котором мы храним удаленные элементы&lt;br /&gt;
  used = list&amp;lt;int&amp;gt;();&lt;br /&gt;
  fl = ''false''&lt;br /&gt;
  '''for''' i = a.size '''downto''' 1&lt;br /&gt;
      '''if''' (used.size &amp;lt;&amp;gt; 0) and (used[used.size] &amp;gt; a[i][a[i].size]) '''then'''   //если можем добавить в конец подмножества элемент из used&lt;br /&gt;
          a[i].add(used[used.size]);   //добавляем&lt;br /&gt;
          used.remove(used.size);&lt;br /&gt;
          '''break'''&lt;br /&gt;
      '''for''' j = a[i].size '''downto''' 1&lt;br /&gt;
          '''if''' (used.size &amp;lt;&amp;gt; 0) and (j &amp;lt;&amp;gt; 1) and (used[used.size] &amp;gt; a[i][j]) '''then'''   //если можем заменить элемент, другим элементом из списка used &lt;br /&gt;
             a[i][j] = used[used.size];   //заменяем&lt;br /&gt;
             fl = ''true''&lt;br /&gt;
             '''break'''&lt;br /&gt;
          used.add(a[i][j]);   // добавляем в used j элемент i-го подмножества  &lt;br /&gt;
          a[i].remove(j);   // удаляем j элемент i-го подмножества&lt;br /&gt;
      '''if''' (fl) '''break'''&lt;br /&gt;
  // далее выведем все получившиеся подмножества&lt;br /&gt;
  sort(used)&lt;br /&gt;
  '''for''' i = 1 '''to''' used.size&lt;br /&gt;
     a.add(list&amp;lt;int&amp;gt;(used[i]));        // добавляем лексикографически минимальных хвост&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;
* [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>91.122.22.64</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=35108</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=35108"/>
				<updated>2014-01-04T22:49:42Z</updated>
		
		<summary type="html">&lt;p&gt;91.122.22.64: /* Специализация алгоритма для генерации следующего разбиения на подмножества */&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;
== Специализация алгоритма для генерации следующего [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 битового вектора] ==&lt;br /&gt;
* Находим минимальный суффикс, в котором есть 0, его можно увеличить, не меняя оставшейся части&lt;br /&gt;
* Вместо 0 записываем 1 &lt;br /&gt;
* Дописываем минимально возможный хвост из нулей&lt;br /&gt;
     '''function''' nextVector(a:array[1..n] of byte):array[1..n] of byte; // n - длина вектора&lt;br /&gt;
      '''for''' i = n '''downto''' 1&lt;br /&gt;
       '''if''' a[i] == 0&lt;br /&gt;
        a[i] = 1&lt;br /&gt;
        '''for''' j = i + 1 to n&lt;br /&gt;
         a[j] = 0&lt;br /&gt;
         '''break'''&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||style=&amp;quot;background:#FFCC00&amp;quot;|0||1||1||исходный битовый вектор&lt;br /&gt;
|-&lt;br /&gt;
| || ||^|| || ||находим элемент 0 (самый правый)&lt;br /&gt;
|-&lt;br /&gt;
|0||1||style=&amp;quot;background:#FFCC00&amp;quot;|1||1||1||меняем его на 1&lt;br /&gt;
|-&lt;br /&gt;
|0||1||1||style=&amp;quot;background:#FFCC00&amp;quot;|0||style=&amp;quot;background:#FFCC00&amp;quot;|0||меняем элементы правее на нули&lt;br /&gt;
|-&lt;br /&gt;
|'''0'''||'''1'''||'''1'''||'''0'''||'''0'''||следующий битовый вектор&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 следующей перестановки] ==&lt;br /&gt;
* Двигаясь справа налево, находим элемент, нарушающий убывающую последовательность (в обычном порядке, слева направо, см. пример)&lt;br /&gt;
* Меняем его с минимальным элементом, большим нашего, стоящим правее&lt;br /&gt;
* Перевернем правую часть&lt;br /&gt;
&lt;br /&gt;
  '''function''' nextPermutation(a:array[1..n] of integer):array[1..n] of integer; // n - длина перестановки&lt;br /&gt;
   '''for''' i = n - 1 '''downto''' 1&lt;br /&gt;
       '''if''' a[i] &amp;lt; a[i + 1]&lt;br /&gt;
           '''for''' j = i + 1 '''to''' n&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[j])&lt;br /&gt;
           reverse(a[i + 1]..a[n])&lt;br /&gt;
           '''break'''&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;
|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;
== Специализация алгоритма для генерации следующей [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 мультиперестановки] ==&lt;br /&gt;
* Двигаясь справа налево, находим элемент, нарушающий убывающую последовательность (в обычном порядке, слева направо, см. пример).&lt;br /&gt;
* Меняем его с минимальным элементом, большим нашего, стоящим правее.&lt;br /&gt;
* Переворачиваем правую часть.&lt;br /&gt;
 '''function''' nextMultiperm(var b:array[1..N] of integer): array[1..N] of integer;&lt;br /&gt;
   '''var''' i , j : '''integer''';&lt;br /&gt;
   '''begin'''&lt;br /&gt;
    i := N - 1;&lt;br /&gt;
    '''while''' (i &amp;gt; 0) '''and''' (b[i] &amp;gt;= b[i + 1]) '''do'''&lt;br /&gt;
     dec(i);&lt;br /&gt;
    '''if''' i &amp;gt; 0 '''then'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
       j := i + 1;&lt;br /&gt;
       '''while''' (j &amp;lt; N) '''and''' (b[j + 1] &amp;gt; b[i]) '''do'''&lt;br /&gt;
         inc(j);&lt;br /&gt;
       swap(b[i] , b[j]);&lt;br /&gt;
       '''for''' j := i + 1 '''to''' (N + i) '''div''' 2 '''do'''&lt;br /&gt;
         swap(b[j], b[N - j + i + 1]);&lt;br /&gt;
       return(b[1..N]);&lt;br /&gt;
     '''end'''&lt;br /&gt;
    '''else'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
       return(null);&lt;br /&gt;
     '''end;'''&lt;br /&gt;
   '''end;'''&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;
== Специализация алгоритма для генерации [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 следующего сочетания] ==&lt;br /&gt;
&lt;br /&gt;
* Добавим в конец массива с сочетанием N+1 – максимальный элемент.&lt;br /&gt;
* Пойдём справа налево. Будем искать номер элемента, который отличается от предыдущего на 2.&lt;br /&gt;
* Увеличим найденный элемент на 1, и допишем в конец минимально возможный хвост, если такого элемента нет – на вход было дано последнее сочетание.&lt;br /&gt;
 '''function''' nextChoose(var a:array[1..k] of integer): array[1..k] of integer; // n,k - параметры сочетания.&lt;br /&gt;
  '''var''' &lt;br /&gt;
   i,j : '''integer;'''&lt;br /&gt;
   b:array[1..k+1] of '''integer;'''&lt;br /&gt;
  '''begin'''&lt;br /&gt;
   '''for''' i := 1 '''to''' k '''do'''&lt;br /&gt;
    b[i]:=a[i];&lt;br /&gt;
   b[k + 1] := n + 1;&lt;br /&gt;
   i := n;&lt;br /&gt;
   '''while''' (i &amp;gt; 0) '''and''' ((b[i + 1] - b[i]) &amp;lt; 2) '''do'''&lt;br /&gt;
     i := i - 1;&lt;br /&gt;
   '''if''' i &amp;gt; 0 '''then'''&lt;br /&gt;
    '''begin'''&lt;br /&gt;
      b[i] := b[i] + 1;&lt;br /&gt;
      '''for''' j := i + 1 '''to''' k '''do'''&lt;br /&gt;
       b[j] := b[j - 1] + 1;&lt;br /&gt;
      '''for''' i := 1 '''to''' k '''do'''&lt;br /&gt;
       a[i] := b[i];&lt;br /&gt;
      return(a[1..k]);&lt;br /&gt;
    '''end'''&lt;br /&gt;
   '''else'''&lt;br /&gt;
    return(null);&lt;br /&gt;
  '''end;'''&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;
== Специализация алгоритма для генерации следующего [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 разбиения на слагаемые] ==&lt;br /&gt;
Рассматриваемый алгоритм находит следующее разбиение на слагаемые, при этом разбиение упорядоченно по возрастанию.&lt;br /&gt;
* Увеличим предпоследнее слагаемое на 1, уменьшим последнее слагаемое на 1.&lt;br /&gt;
** Если предпоследнее слагаемое стало больше последнего, то увеличиваем предпоследнее слагаемое на величину последнего.&lt;br /&gt;
** Если предпоследнее слагаемое меньше последнего, то разбиваем последнее слагаемое &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;
 // b – список, содержащий разбиение данного числа, length – его размер.&lt;br /&gt;
 '''function''' nextPartition(var b: list&amp;lt;int&amp;gt;): list&amp;lt;int&amp;gt;;&lt;br /&gt;
  '''var''' i : '''integer;'''&lt;br /&gt;
   '''begin'''   &lt;br /&gt;
    b[b.size] := b[b.size] - 1;&lt;br /&gt;
    b[b.size - 1] := b[b.size - 1] + 1;&lt;br /&gt;
    '''if''' b[b.size - 1] &amp;gt; b[b.size] '''then'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
       b[b.size - 1] := b[b.size - 1] + b[b.size];&lt;br /&gt;
       b.pop();&lt;br /&gt;
     '''end'''&lt;br /&gt;
    '''else'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
      '''while''' b[b.size - 1] * 2 &amp;lt;= b[b.size] '''do'''&lt;br /&gt;
       '''begin'''&lt;br /&gt;
        b.add(b[b.size] - b[b.size - 1]);&lt;br /&gt;
        b[b.size - 1] := b[b.size - 2];&lt;br /&gt;
       '''end;'''&lt;br /&gt;
     '''end;'''&lt;br /&gt;
    '''return''' b;&lt;br /&gt;
   '''end;'''&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 пока оно не станет &amp;lt;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;
== Специализация алгоритма для генерации следующего [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 разбиения на подмножества] ==&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;
** Заменить рассматриваемый элемент уже удаленным. Из всех подходящих элементов выбираем минимальный. '''Важное замечание''': мы не можем заменить 1ый элемент подмножества, мы можем только удалить его.&lt;br /&gt;
** Дополнить рассматриваемое подмножество уже удаленным элементом. Из всех подходящих элементов выбираем минимальный.&lt;br /&gt;
* Допишем лексикографически минимальный хвост подмножеств из оставшихся элементов.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 '''function''' nextSetPartition(a:list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;):list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;;&lt;br /&gt;
  // a - список, содержащий подмножества&lt;br /&gt;
  // used - список, в котором мы храним удаленные элементы&lt;br /&gt;
  used = list&amp;lt;int&amp;gt;();&lt;br /&gt;
  fl = ''false''&lt;br /&gt;
  '''for''' i = a.size '''downto''' 1&lt;br /&gt;
      '''if''' (used.size &amp;lt;&amp;gt; 0) and (used[used.size] &amp;gt; a[i][a[i].size]) '''then'''   //если можем добавить в конец подмножества элемент из used&lt;br /&gt;
          a[i].add(used[used.size]);   //добавляем&lt;br /&gt;
          '''break'''&lt;br /&gt;
      '''for''' j = a[i].size '''downto''' 1&lt;br /&gt;
          '''if''' (used.size &amp;lt;&amp;gt; 0) and (j &amp;lt;&amp;gt; 1) and (used[used.size] &amp;gt; a[i][j]) '''then'''   //если можем заменить элемент, другим элементом из списка used &lt;br /&gt;
             a[i][j] = used[used.size];   //заменяем&lt;br /&gt;
             fl = ''true''&lt;br /&gt;
             '''break'''&lt;br /&gt;
          used.add(a[i][j]);&lt;br /&gt;
          a[i].pop(j);   // удаляем j элемент i-го подмножества и добавляем его в список&lt;br /&gt;
      '''if''' (fl) '''break'''&lt;br /&gt;
  // далее выведем все получившиеся подмножества&lt;br /&gt;
  sort(used)&lt;br /&gt;
  '''for''' i = 1 '''to''' used.size&lt;br /&gt;
     a.add(list&amp;lt;int&amp;gt;(used[i]));        // добавляем лексикографически минимальных хвост&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;
* [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>91.122.22.64</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=35103</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=35103"/>
				<updated>2014-01-04T22:34:40Z</updated>
		
		<summary type="html">&lt;p&gt;91.122.22.64: /* Специализация алгоритма для генерации следующего разбиения на подмножества */&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;
== Специализация алгоритма для генерации следующего [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 битового вектора] ==&lt;br /&gt;
* Находим минимальный суффикс, в котором есть 0, его можно увеличить, не меняя оставшейся части&lt;br /&gt;
* Вместо 0 записываем 1 &lt;br /&gt;
* Дописываем минимально возможный хвост из нулей&lt;br /&gt;
     '''function''' nextVector(a:array[1..n] of byte):array[1..n] of byte; // n - длина вектора&lt;br /&gt;
      '''for''' i = n '''downto''' 1&lt;br /&gt;
       '''if''' a[i] == 0&lt;br /&gt;
        a[i] = 1&lt;br /&gt;
        '''for''' j = i + 1 to n&lt;br /&gt;
         a[j] = 0&lt;br /&gt;
         '''break'''&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||style=&amp;quot;background:#FFCC00&amp;quot;|0||1||1||исходный битовый вектор&lt;br /&gt;
|-&lt;br /&gt;
| || ||^|| || ||находим элемент 0 (самый правый)&lt;br /&gt;
|-&lt;br /&gt;
|0||1||style=&amp;quot;background:#FFCC00&amp;quot;|1||1||1||меняем его на 1&lt;br /&gt;
|-&lt;br /&gt;
|0||1||1||style=&amp;quot;background:#FFCC00&amp;quot;|0||style=&amp;quot;background:#FFCC00&amp;quot;|0||меняем элементы правее на нули&lt;br /&gt;
|-&lt;br /&gt;
|'''0'''||'''1'''||'''1'''||'''0'''||'''0'''||следующий битовый вектор&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 следующей перестановки] ==&lt;br /&gt;
* Двигаясь справа налево, находим элемент, нарушающий убывающую последовательность (в обычном порядке, слева направо, см. пример)&lt;br /&gt;
* Меняем его с минимальным элементом, большим нашего, стоящим правее&lt;br /&gt;
* Перевернем правую часть&lt;br /&gt;
&lt;br /&gt;
  '''function''' nextPermutation(a:array[1..n] of integer):array[1..n] of integer; // n - длина перестановки&lt;br /&gt;
   '''for''' i = n - 1 '''downto''' 1&lt;br /&gt;
       '''if''' a[i] &amp;lt; a[i + 1]&lt;br /&gt;
           '''for''' j = i + 1 '''to''' n&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[j])&lt;br /&gt;
           reverse(a[i + 1]..a[n])&lt;br /&gt;
           '''break'''&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;
|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;
== Специализация алгоритма для генерации следующей [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 мультиперестановки] ==&lt;br /&gt;
* Двигаясь справа налево, находим элемент, нарушающий убывающую последовательность (в обычном порядке, слева направо, см. пример).&lt;br /&gt;
* Меняем его с минимальным элементом, большим нашего, стоящим правее.&lt;br /&gt;
* Переворачиваем правую часть.&lt;br /&gt;
 '''function''' nextMultiperm(var b:array[1..N] of integer): array[1..N] of integer;&lt;br /&gt;
   '''var''' i , j : '''integer''';&lt;br /&gt;
   '''begin'''&lt;br /&gt;
    i := N - 1;&lt;br /&gt;
    '''while''' (i &amp;gt; 0) '''and''' (b[i] &amp;gt;= b[i + 1]) '''do'''&lt;br /&gt;
     dec(i);&lt;br /&gt;
    '''if''' i &amp;gt; 0 '''then'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
       j := i + 1;&lt;br /&gt;
       '''while''' (j &amp;lt; N) '''and''' (b[j + 1] &amp;gt; b[i]) '''do'''&lt;br /&gt;
         inc(j);&lt;br /&gt;
       swap(b[i] , b[j]);&lt;br /&gt;
       '''for''' j := i + 1 '''to''' (N + i) '''div''' 2 '''do'''&lt;br /&gt;
         swap(b[j], b[N - j + i + 1]);&lt;br /&gt;
       return(b[1..N]);&lt;br /&gt;
     '''end'''&lt;br /&gt;
    '''else'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
       return(null);&lt;br /&gt;
     '''end;'''&lt;br /&gt;
   '''end;'''&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;
== Специализация алгоритма для генерации [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 следующего сочетания] ==&lt;br /&gt;
&lt;br /&gt;
* Добавим в конец массива с сочетанием N+1 – максимальный элемент.&lt;br /&gt;
* Пойдём справа налево. Будем искать номер элемента, который отличается от предыдущего на 2.&lt;br /&gt;
* Увеличим найденный элемент на 1, и допишем в конец минимально возможный хвост, если такого элемента нет – на вход было дано последнее сочетание.&lt;br /&gt;
 '''function''' nextChoose(var a:array[1..k] of integer): array[1..k] of integer; // n,k - параметры сочетания.&lt;br /&gt;
  '''var''' &lt;br /&gt;
   i,j : '''integer;'''&lt;br /&gt;
   b:array[1..k+1] of '''integer;'''&lt;br /&gt;
  '''begin'''&lt;br /&gt;
   '''for''' i := 1 '''to''' k '''do'''&lt;br /&gt;
    b[i]:=a[i];&lt;br /&gt;
   b[k + 1] := n + 1;&lt;br /&gt;
   i := n;&lt;br /&gt;
   '''while''' (i &amp;gt; 0) '''and''' ((b[i + 1] - b[i]) &amp;lt; 2) '''do'''&lt;br /&gt;
     i := i - 1;&lt;br /&gt;
   '''if''' i &amp;gt; 0 '''then'''&lt;br /&gt;
    '''begin'''&lt;br /&gt;
      b[i] := b[i] + 1;&lt;br /&gt;
      '''for''' j := i + 1 '''to''' k '''do'''&lt;br /&gt;
       b[j] := b[j - 1] + 1;&lt;br /&gt;
      '''for''' i := 1 '''to''' k '''do'''&lt;br /&gt;
       a[i] := b[i];&lt;br /&gt;
      return(a[1..k]);&lt;br /&gt;
    '''end'''&lt;br /&gt;
   '''else'''&lt;br /&gt;
    return(null);&lt;br /&gt;
  '''end;'''&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;
== Специализация алгоритма для генерации следующего [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 разбиения на слагаемые] ==&lt;br /&gt;
Рассматриваемый алгоритм находит следующее разбиение на слагаемые, при этом разбиение упорядоченно по возрастанию.&lt;br /&gt;
* Увеличим предпоследнее слагаемое на 1, уменьшим последнее слагаемое на 1.&lt;br /&gt;
** Если предпоследнее слагаемое стало больше последнего, то увеличиваем предпоследнее слагаемое на величину последнего.&lt;br /&gt;
** Если предпоследнее слагаемое меньше последнего, то разбиваем последнее слагаемое &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;
 // b – список, содержащий разбиение данного числа, length – его размер.&lt;br /&gt;
 '''function''' nextPartition(var b: list&amp;lt;int&amp;gt;): list&amp;lt;int&amp;gt;;&lt;br /&gt;
  '''var''' i : '''integer;'''&lt;br /&gt;
   '''begin'''   &lt;br /&gt;
    b[b.size] := b[b.size] - 1;&lt;br /&gt;
    b[b.size - 1] := b[b.size - 1] + 1;&lt;br /&gt;
    '''if''' b[b.size - 1] &amp;gt; b[b.size] '''then'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
       b[b.size - 1] := b[b.size - 1] + b[b.size];&lt;br /&gt;
       b.pop();&lt;br /&gt;
     '''end'''&lt;br /&gt;
    '''else'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
      '''while''' b[b.size - 1] * 2 &amp;lt;= b[b.size] '''do'''&lt;br /&gt;
       '''begin'''&lt;br /&gt;
        b.add(b[b.size] - b[b.size - 1]);&lt;br /&gt;
        b[b.size - 1] := b[b.size - 2];&lt;br /&gt;
       '''end;'''&lt;br /&gt;
     '''end;'''&lt;br /&gt;
    '''return''' b;&lt;br /&gt;
   '''end;'''&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 пока оно не станет &amp;lt;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;
== Специализация алгоритма для генерации следующего [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 разбиения на подмножества] ==&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;
** Заменить рассматриваемый элемент уже удаленным. Из всех подходящих элементов выбираем минимальный. '''Важное замечание''': мы не можем заменить 1ый элемент подмножества, мы можем только удалить его.&lt;br /&gt;
** Дополнить рассматриваемое подмножество уже удаленным элементом. Из всех подходящих элементов выбираем минимальный.&lt;br /&gt;
* Допишем лексикографически минимальный хвост подмножеств из оставшихся элементов.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 '''function''' nextSetPartition(a:list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;):list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;;&lt;br /&gt;
  // a - список, содержащий подмножества&lt;br /&gt;
  // used - список, в котором мы храним удаленные элементы&lt;br /&gt;
  used = list&amp;lt;int&amp;gt;();&lt;br /&gt;
  fl = ''false''&lt;br /&gt;
  '''for''' i = a.size '''downto''' 1&lt;br /&gt;
      '''if'''  used[used.size] &amp;gt; a[i][a[i].size] '''then'''   //если можем добавить в конец подмножества элемент из used&lt;br /&gt;
          a[i].add(used[used.size]);   //добавляем&lt;br /&gt;
          '''break'''&lt;br /&gt;
      '''for''' j = a[i].size '''downto''' 1&lt;br /&gt;
          '''if''' (j &amp;lt;&amp;gt; 1) and used[used.size] &amp;gt; a[i][j] '''then'''   //если можем заменить элемент, другим элементом из списка used &lt;br /&gt;
             a[i][j] = used[used.size];   //заменяем&lt;br /&gt;
             fl = ''true''&lt;br /&gt;
             '''break'''&lt;br /&gt;
          used.add(a[i][j]);&lt;br /&gt;
          a[i].pop(j);   // удаляем j элемент i подмножества и добавляем его в список&lt;br /&gt;
      '''if''' (fl) '''break'''&lt;br /&gt;
  // далее выведем все получившиеся подмножества&lt;br /&gt;
  sort(used)&lt;br /&gt;
  '''for''' i = 1 '''to''' used.size&lt;br /&gt;
     a.add(used[i]);        // добавляем лексикографически минимальных хвост&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;
* [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>91.122.22.64</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=35099</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=35099"/>
				<updated>2014-01-04T21:52:45Z</updated>
		
		<summary type="html">&lt;p&gt;91.122.22.64: /* Специализация алгоритма для генерации следующего разбиения на подмножества */&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;
== Специализация алгоритма для генерации следующего [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 битового вектора] ==&lt;br /&gt;
* Находим минимальный суффикс, в котором есть 0, его можно увеличить, не меняя оставшейся части&lt;br /&gt;
* Вместо 0 записываем 1 &lt;br /&gt;
* Дописываем минимально возможный хвост из нулей&lt;br /&gt;
     '''function''' nextVector(a:array[1..n] of byte):array[1..n] of byte; // n - длина вектора&lt;br /&gt;
      '''for''' i = n '''downto''' 1&lt;br /&gt;
       '''if''' a[i] == 0&lt;br /&gt;
        a[i] = 1&lt;br /&gt;
        '''for''' j = i + 1 to n&lt;br /&gt;
         a[j] = 0&lt;br /&gt;
         '''break'''&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||style=&amp;quot;background:#FFCC00&amp;quot;|0||1||1||исходный битовый вектор&lt;br /&gt;
|-&lt;br /&gt;
| || ||^|| || ||находим элемент 0 (самый правый)&lt;br /&gt;
|-&lt;br /&gt;
|0||1||style=&amp;quot;background:#FFCC00&amp;quot;|1||1||1||меняем его на 1&lt;br /&gt;
|-&lt;br /&gt;
|0||1||1||style=&amp;quot;background:#FFCC00&amp;quot;|0||style=&amp;quot;background:#FFCC00&amp;quot;|0||меняем элементы правее на нули&lt;br /&gt;
|-&lt;br /&gt;
|'''0'''||'''1'''||'''1'''||'''0'''||'''0'''||следующий битовый вектор&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 следующей перестановки] ==&lt;br /&gt;
* Двигаясь справа налево, находим элемент, нарушающий убывающую последовательность (в обычном порядке, слева направо, см. пример)&lt;br /&gt;
* Меняем его с минимальным элементом, большим нашего, стоящим правее&lt;br /&gt;
* Перевернем правую часть&lt;br /&gt;
&lt;br /&gt;
  '''function''' nextPermutation(a:array[1..n] of integer):array[1..n] of integer; // n - длина перестановки&lt;br /&gt;
   '''for''' i = n - 1 '''downto''' 1&lt;br /&gt;
       '''if''' a[i] &amp;lt; a[i + 1]&lt;br /&gt;
           '''for''' j = i + 1 '''to''' n&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[j])&lt;br /&gt;
           reverse(a[i + 1]..a[n])&lt;br /&gt;
           '''break'''&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;
|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;
== Специализация алгоритма для генерации следующей [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 мультиперестановки] ==&lt;br /&gt;
* Двигаясь справа налево, находим элемент, нарушающий убывающую последовательность (в обычном порядке, слева направо, см. пример).&lt;br /&gt;
* Меняем его с минимальным элементом, большим нашего, стоящим правее.&lt;br /&gt;
* Переворачиваем правую часть.&lt;br /&gt;
 '''function''' nextMultiperm(var b:array[1..N] of integer): array[1..N] of integer;&lt;br /&gt;
   '''var''' i , j : '''integer''';&lt;br /&gt;
   '''begin'''&lt;br /&gt;
    i := N - 1;&lt;br /&gt;
    '''while''' (i &amp;gt; 0) '''and''' (b[i] &amp;gt;= b[i + 1]) '''do'''&lt;br /&gt;
     dec(i);&lt;br /&gt;
    '''if''' i &amp;gt; 0 '''then'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
       j := i + 1;&lt;br /&gt;
       '''while''' (j &amp;lt; N) '''and''' (b[j + 1] &amp;gt; b[i]) '''do'''&lt;br /&gt;
         inc(j);&lt;br /&gt;
       swap(b[i] , b[j]);&lt;br /&gt;
       '''for''' j := i + 1 '''to''' (N + i) '''div''' 2 '''do'''&lt;br /&gt;
         swap(b[j], b[N - j + i + 1]);&lt;br /&gt;
       return(b[1..N]);&lt;br /&gt;
     '''end'''&lt;br /&gt;
    '''else'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
       return(null);&lt;br /&gt;
     '''end;'''&lt;br /&gt;
   '''end;'''&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;
== Специализация алгоритма для генерации [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 следующего сочетания] ==&lt;br /&gt;
&lt;br /&gt;
* Добавим в конец массива с сочетанием N+1 – максимальный элемент.&lt;br /&gt;
* Пойдём справа налево. Будем искать номер элемента, который отличается от предыдущего на 2.&lt;br /&gt;
* Увеличим найденный элемент на 1, и допишем в конец минимально возможный хвост, если такого элемента нет – на вход было дано последнее сочетание.&lt;br /&gt;
 '''function''' nextChoose(var a:array[1..k] of integer): array[1..k] of integer; // n,k - параметры сочетания.&lt;br /&gt;
  '''var''' &lt;br /&gt;
   i,j : '''integer;'''&lt;br /&gt;
   b:array[1..k+1] of '''integer;'''&lt;br /&gt;
  '''begin'''&lt;br /&gt;
   '''for''' i := 1 '''to''' k '''do'''&lt;br /&gt;
    b[i]:=a[i];&lt;br /&gt;
   b[k + 1] := n + 1;&lt;br /&gt;
   i := n;&lt;br /&gt;
   '''while''' (i &amp;gt; 0) '''and''' ((b[i + 1] - b[i]) &amp;lt; 2) '''do'''&lt;br /&gt;
     i := i - 1;&lt;br /&gt;
   '''if''' i &amp;gt; 0 '''then'''&lt;br /&gt;
    '''begin'''&lt;br /&gt;
      b[i] := b[i] + 1;&lt;br /&gt;
      '''for''' j := i + 1 '''to''' k '''do'''&lt;br /&gt;
       b[j] := b[j - 1] + 1;&lt;br /&gt;
      '''for''' i := 1 '''to''' k '''do'''&lt;br /&gt;
       a[i] := b[i];&lt;br /&gt;
      return(a[1..k]);&lt;br /&gt;
    '''end'''&lt;br /&gt;
   '''else'''&lt;br /&gt;
    return(null);&lt;br /&gt;
  '''end;'''&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;
== Специализация алгоритма для генерации следующего [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 разбиения на слагаемые] ==&lt;br /&gt;
Рассматриваемый алгоритм находит следующее разбиение на слагаемые, при этом разбиение упорядоченно по возрастанию.&lt;br /&gt;
* Увеличим предпоследнее слагаемое на 1, уменьшим последнее слагаемое на 1.&lt;br /&gt;
** Если предпоследнее слагаемое стало больше последнего, то увеличиваем предпоследнее слагаемое на величину последнего.&lt;br /&gt;
** Если предпоследнее слагаемое меньше последнего, то разбиваем последнее слагаемое &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;
 // b – список, содержащий разбиение данного числа, length – его размер.&lt;br /&gt;
 '''function''' nextPartition(var b: list&amp;lt;int&amp;gt;): list&amp;lt;int&amp;gt;;&lt;br /&gt;
  '''var''' i : '''integer;'''&lt;br /&gt;
   '''begin'''   &lt;br /&gt;
    b[b.size] := b[b.size] - 1;&lt;br /&gt;
    b[b.size - 1] := b[b.size - 1] + 1;&lt;br /&gt;
    '''if''' b[b.size - 1] &amp;gt; b[b.size] '''then'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
       b[b.size - 1] := b[b.size - 1] + b[b.size];&lt;br /&gt;
       b.pop();&lt;br /&gt;
     '''end'''&lt;br /&gt;
    '''else'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
      '''while''' b[b.size - 1] * 2 &amp;lt;= b[b.size] '''do'''&lt;br /&gt;
       '''begin'''&lt;br /&gt;
        b.add(b[b.size] - b[b.size - 1]);&lt;br /&gt;
        b[b.size - 1] := b[b.size - 2];&lt;br /&gt;
       '''end;'''&lt;br /&gt;
     '''end;'''&lt;br /&gt;
    '''return''' b;&lt;br /&gt;
   '''end;'''&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 пока оно не станет &amp;lt;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;
== Специализация алгоритма для генерации следующего [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 разбиения на подмножества] ==&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;
** Заменить рассматриваемый элемент уже удаленным. Из всех подходящих элементов выбираем минимальный. '''Важное замечание''': мы не можем заменить 1ый элемент подмножества, мы можем только удалить его.&lt;br /&gt;
** Дополнить рассматриваемое подмножество уже удаленным элементом. Из всех подходящих элементов выбираем минимальный.&lt;br /&gt;
* Допишем лексикографически минимальный хвост подмножеств из оставшихся элементов.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 '''function''' nextSetPartition(a:list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;):list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;;&lt;br /&gt;
  // индексация списка идет от 0&lt;br /&gt;
  // a - список, содержащий подмножества&lt;br /&gt;
  // used - список, в котором мы храним удаленные элементы&lt;br /&gt;
  used = list&amp;lt;int&amp;gt;();&lt;br /&gt;
  fl = ''false''&lt;br /&gt;
  '''for''' i = a.size '''downto''' 1&lt;br /&gt;
      '''if'''  used[used.size] &amp;gt; a[i][a[i].size] '''then'''   //если можем добавить в конец подмножества элемент из used&lt;br /&gt;
          a[i].add(used[used.size]);   //добавляем&lt;br /&gt;
          '''break'''&lt;br /&gt;
      '''for''' j = a[i].size '''downto''' 1&lt;br /&gt;
          '''if''' (j &amp;lt;&amp;gt; 1) and used[used.size] &amp;gt; a[i][j] '''then'''   //если можем заменить элемент, другим элементом из списка used &lt;br /&gt;
             a[i][j] = used[used.size];   //заменяем&lt;br /&gt;
             fl = ''true''&lt;br /&gt;
             '''break'''&lt;br /&gt;
          used.add(a[i][j]);&lt;br /&gt;
          a[i].pop(j);   // удаляем j элемент i подмножества и добавляем его в список&lt;br /&gt;
      '''if''' (fl) '''break'''&lt;br /&gt;
  // далее выведем все получившиеся подмножества&lt;br /&gt;
  sort(used)&lt;br /&gt;
  '''for''' i = 1 '''to''' used.size&lt;br /&gt;
     a.add(used[i]);        // добавляем лексикографически минимальных хвост&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;
* [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>91.122.22.64</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=35098</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=35098"/>
				<updated>2014-01-04T21:47:35Z</updated>
		
		<summary type="html">&lt;p&gt;91.122.22.64: /* Специализация алгоритма для генерации следующего разбиения на слагаемые */&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;
== Специализация алгоритма для генерации следующего [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 битового вектора] ==&lt;br /&gt;
* Находим минимальный суффикс, в котором есть 0, его можно увеличить, не меняя оставшейся части&lt;br /&gt;
* Вместо 0 записываем 1 &lt;br /&gt;
* Дописываем минимально возможный хвост из нулей&lt;br /&gt;
     '''function''' nextVector(a:array[1..n] of byte):array[1..n] of byte; // n - длина вектора&lt;br /&gt;
      '''for''' i = n '''downto''' 1&lt;br /&gt;
       '''if''' a[i] == 0&lt;br /&gt;
        a[i] = 1&lt;br /&gt;
        '''for''' j = i + 1 to n&lt;br /&gt;
         a[j] = 0&lt;br /&gt;
         '''break'''&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||style=&amp;quot;background:#FFCC00&amp;quot;|0||1||1||исходный битовый вектор&lt;br /&gt;
|-&lt;br /&gt;
| || ||^|| || ||находим элемент 0 (самый правый)&lt;br /&gt;
|-&lt;br /&gt;
|0||1||style=&amp;quot;background:#FFCC00&amp;quot;|1||1||1||меняем его на 1&lt;br /&gt;
|-&lt;br /&gt;
|0||1||1||style=&amp;quot;background:#FFCC00&amp;quot;|0||style=&amp;quot;background:#FFCC00&amp;quot;|0||меняем элементы правее на нули&lt;br /&gt;
|-&lt;br /&gt;
|'''0'''||'''1'''||'''1'''||'''0'''||'''0'''||следующий битовый вектор&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 следующей перестановки] ==&lt;br /&gt;
* Двигаясь справа налево, находим элемент, нарушающий убывающую последовательность (в обычном порядке, слева направо, см. пример)&lt;br /&gt;
* Меняем его с минимальным элементом, большим нашего, стоящим правее&lt;br /&gt;
* Перевернем правую часть&lt;br /&gt;
&lt;br /&gt;
  '''function''' nextPermutation(a:array[1..n] of integer):array[1..n] of integer; // n - длина перестановки&lt;br /&gt;
   '''for''' i = n - 1 '''downto''' 1&lt;br /&gt;
       '''if''' a[i] &amp;lt; a[i + 1]&lt;br /&gt;
           '''for''' j = i + 1 '''to''' n&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[j])&lt;br /&gt;
           reverse(a[i + 1]..a[n])&lt;br /&gt;
           '''break'''&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;
|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;
== Специализация алгоритма для генерации следующей [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 мультиперестановки] ==&lt;br /&gt;
* Двигаясь справа налево, находим элемент, нарушающий убывающую последовательность (в обычном порядке, слева направо, см. пример).&lt;br /&gt;
* Меняем его с минимальным элементом, большим нашего, стоящим правее.&lt;br /&gt;
* Переворачиваем правую часть.&lt;br /&gt;
 '''function''' nextMultiperm(var b:array[1..N] of integer): array[1..N] of integer;&lt;br /&gt;
   '''var''' i , j : '''integer''';&lt;br /&gt;
   '''begin'''&lt;br /&gt;
    i := N - 1;&lt;br /&gt;
    '''while''' (i &amp;gt; 0) '''and''' (b[i] &amp;gt;= b[i + 1]) '''do'''&lt;br /&gt;
     dec(i);&lt;br /&gt;
    '''if''' i &amp;gt; 0 '''then'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
       j := i + 1;&lt;br /&gt;
       '''while''' (j &amp;lt; N) '''and''' (b[j + 1] &amp;gt; b[i]) '''do'''&lt;br /&gt;
         inc(j);&lt;br /&gt;
       swap(b[i] , b[j]);&lt;br /&gt;
       '''for''' j := i + 1 '''to''' (N + i) '''div''' 2 '''do'''&lt;br /&gt;
         swap(b[j], b[N - j + i + 1]);&lt;br /&gt;
       return(b[1..N]);&lt;br /&gt;
     '''end'''&lt;br /&gt;
    '''else'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
       return(null);&lt;br /&gt;
     '''end;'''&lt;br /&gt;
   '''end;'''&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;
== Специализация алгоритма для генерации [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 следующего сочетания] ==&lt;br /&gt;
&lt;br /&gt;
* Добавим в конец массива с сочетанием N+1 – максимальный элемент.&lt;br /&gt;
* Пойдём справа налево. Будем искать номер элемента, который отличается от предыдущего на 2.&lt;br /&gt;
* Увеличим найденный элемент на 1, и допишем в конец минимально возможный хвост, если такого элемента нет – на вход было дано последнее сочетание.&lt;br /&gt;
 '''function''' nextChoose(var a:array[1..k] of integer): array[1..k] of integer; // n,k - параметры сочетания.&lt;br /&gt;
  '''var''' &lt;br /&gt;
   i,j : '''integer;'''&lt;br /&gt;
   b:array[1..k+1] of '''integer;'''&lt;br /&gt;
  '''begin'''&lt;br /&gt;
   '''for''' i := 1 '''to''' k '''do'''&lt;br /&gt;
    b[i]:=a[i];&lt;br /&gt;
   b[k + 1] := n + 1;&lt;br /&gt;
   i := n;&lt;br /&gt;
   '''while''' (i &amp;gt; 0) '''and''' ((b[i + 1] - b[i]) &amp;lt; 2) '''do'''&lt;br /&gt;
     i := i - 1;&lt;br /&gt;
   '''if''' i &amp;gt; 0 '''then'''&lt;br /&gt;
    '''begin'''&lt;br /&gt;
      b[i] := b[i] + 1;&lt;br /&gt;
      '''for''' j := i + 1 '''to''' k '''do'''&lt;br /&gt;
       b[j] := b[j - 1] + 1;&lt;br /&gt;
      '''for''' i := 1 '''to''' k '''do'''&lt;br /&gt;
       a[i] := b[i];&lt;br /&gt;
      return(a[1..k]);&lt;br /&gt;
    '''end'''&lt;br /&gt;
   '''else'''&lt;br /&gt;
    return(null);&lt;br /&gt;
  '''end;'''&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;
== Специализация алгоритма для генерации следующего [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 разбиения на слагаемые] ==&lt;br /&gt;
Рассматриваемый алгоритм находит следующее разбиение на слагаемые, при этом разбиение упорядоченно по возрастанию.&lt;br /&gt;
* Увеличим предпоследнее слагаемое на 1, уменьшим последнее слагаемое на 1.&lt;br /&gt;
** Если предпоследнее слагаемое стало больше последнего, то увеличиваем предпоследнее слагаемое на величину последнего.&lt;br /&gt;
** Если предпоследнее слагаемое меньше последнего, то разбиваем последнее слагаемое &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;
 // b – список, содержащий разбиение данного числа, length – его размер.&lt;br /&gt;
 '''function''' nextPartition(var b: list&amp;lt;int&amp;gt;): list&amp;lt;int&amp;gt;;&lt;br /&gt;
  '''var''' i : '''integer;'''&lt;br /&gt;
   '''begin'''   &lt;br /&gt;
    b[b.size] := b[b.size] - 1;&lt;br /&gt;
    b[b.size - 1] := b[b.size - 1] + 1;&lt;br /&gt;
    '''if''' b[b.size - 1] &amp;gt; b[b.size] '''then'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
       b[b.size - 1] := b[b.size - 1] + b[b.size];&lt;br /&gt;
       b.pop();&lt;br /&gt;
     '''end'''&lt;br /&gt;
    '''else'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
      '''while''' b[b.size - 1] * 2 &amp;lt;= b[b.size] '''do'''&lt;br /&gt;
       '''begin'''&lt;br /&gt;
        b.add(b[b.size] - b[b.size - 1]);&lt;br /&gt;
        b[b.size - 1] := b[b.size - 2];&lt;br /&gt;
       '''end;'''&lt;br /&gt;
     '''end;'''&lt;br /&gt;
    '''return''' b;&lt;br /&gt;
   '''end;'''&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 пока оно не станет &amp;lt;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;
== Специализация алгоритма для генерации следующего [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 разбиения на подмножества] ==&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;
** Заменить рассматриваемый элемент уже удаленным. Из всех подходящих элементов выбираем минимальный. '''Важное замечание''': мы не можем заменить 1ый элемент подмножества, мы можем только удалить его.&lt;br /&gt;
** Дополнить рассматриваемое подмножество уже удаленным элементом. Из всех подходящих элементов выбираем минимальный.&lt;br /&gt;
* Допишем лексикографически минимальный хвост подмножеств из оставшихся элементов.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 '''function''' nextSetPartition(a:list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;):list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;;&lt;br /&gt;
  // индексация списка идет от 0&lt;br /&gt;
  // a - список, содержащий подмножества&lt;br /&gt;
  // used - список, в котором мы храним удаленные элементы&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[used.size] &amp;gt; a[i][a[i].size] '''then'''   //если можем добавить в конец подмножества элемент из used&lt;br /&gt;
          a[i].add(used[used.size]);   //добавляем&lt;br /&gt;
          '''break'''&lt;br /&gt;
      '''for''' j = a[i].size - 1 '''downto''' 0&lt;br /&gt;
          '''if''' (j &amp;lt;&amp;gt; 1) and used[used.size] &amp;gt; a[i][j] '''then'''   //если можем заменить элемент, другим элементом из списка used &lt;br /&gt;
             a[i][j] = used[used.size];   //заменяем&lt;br /&gt;
             fl = ''true''&lt;br /&gt;
             '''break'''&lt;br /&gt;
          used.add(a[i][j]);&lt;br /&gt;
          a[i].pop(j);   // удаляем j элемент i подмножества и добавляем его в список&lt;br /&gt;
      '''if''' (fl) '''break'''&lt;br /&gt;
  // далее выведем все получившиеся подмножества&lt;br /&gt;
  sort(used)&lt;br /&gt;
  '''for''' i = 0 '''to''' used.size - 1&lt;br /&gt;
     a.add(used[i]);        // добавляем лексикографически минимальных хвост&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;
* [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>91.122.22.64</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=35097</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=35097"/>
				<updated>2014-01-04T21:43:48Z</updated>
		
		<summary type="html">&lt;p&gt;91.122.22.64: /* Специализация алгоритма для генерации следующего разбиения на слагаемые */&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;
== Специализация алгоритма для генерации следующего [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 битового вектора] ==&lt;br /&gt;
* Находим минимальный суффикс, в котором есть 0, его можно увеличить, не меняя оставшейся части&lt;br /&gt;
* Вместо 0 записываем 1 &lt;br /&gt;
* Дописываем минимально возможный хвост из нулей&lt;br /&gt;
     '''function''' nextVector(a:array[1..n] of byte):array[1..n] of byte; // n - длина вектора&lt;br /&gt;
      '''for''' i = n '''downto''' 1&lt;br /&gt;
       '''if''' a[i] == 0&lt;br /&gt;
        a[i] = 1&lt;br /&gt;
        '''for''' j = i + 1 to n&lt;br /&gt;
         a[j] = 0&lt;br /&gt;
         '''break'''&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||style=&amp;quot;background:#FFCC00&amp;quot;|0||1||1||исходный битовый вектор&lt;br /&gt;
|-&lt;br /&gt;
| || ||^|| || ||находим элемент 0 (самый правый)&lt;br /&gt;
|-&lt;br /&gt;
|0||1||style=&amp;quot;background:#FFCC00&amp;quot;|1||1||1||меняем его на 1&lt;br /&gt;
|-&lt;br /&gt;
|0||1||1||style=&amp;quot;background:#FFCC00&amp;quot;|0||style=&amp;quot;background:#FFCC00&amp;quot;|0||меняем элементы правее на нули&lt;br /&gt;
|-&lt;br /&gt;
|'''0'''||'''1'''||'''1'''||'''0'''||'''0'''||следующий битовый вектор&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 следующей перестановки] ==&lt;br /&gt;
* Двигаясь справа налево, находим элемент, нарушающий убывающую последовательность (в обычном порядке, слева направо, см. пример)&lt;br /&gt;
* Меняем его с минимальным элементом, большим нашего, стоящим правее&lt;br /&gt;
* Перевернем правую часть&lt;br /&gt;
&lt;br /&gt;
  '''function''' nextPermutation(a:array[1..n] of integer):array[1..n] of integer; // n - длина перестановки&lt;br /&gt;
   '''for''' i = n - 1 '''downto''' 1&lt;br /&gt;
       '''if''' a[i] &amp;lt; a[i + 1]&lt;br /&gt;
           '''for''' j = i + 1 '''to''' n&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[j])&lt;br /&gt;
           reverse(a[i + 1]..a[n])&lt;br /&gt;
           '''break'''&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;
|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;
== Специализация алгоритма для генерации следующей [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 мультиперестановки] ==&lt;br /&gt;
* Двигаясь справа налево, находим элемент, нарушающий убывающую последовательность (в обычном порядке, слева направо, см. пример).&lt;br /&gt;
* Меняем его с минимальным элементом, большим нашего, стоящим правее.&lt;br /&gt;
* Переворачиваем правую часть.&lt;br /&gt;
 '''function''' nextMultiperm(var b:array[1..N] of integer): array[1..N] of integer;&lt;br /&gt;
   '''var''' i , j : '''integer''';&lt;br /&gt;
   '''begin'''&lt;br /&gt;
    i := N - 1;&lt;br /&gt;
    '''while''' (i &amp;gt; 0) '''and''' (b[i] &amp;gt;= b[i + 1]) '''do'''&lt;br /&gt;
     dec(i);&lt;br /&gt;
    '''if''' i &amp;gt; 0 '''then'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
       j := i + 1;&lt;br /&gt;
       '''while''' (j &amp;lt; N) '''and''' (b[j + 1] &amp;gt; b[i]) '''do'''&lt;br /&gt;
         inc(j);&lt;br /&gt;
       swap(b[i] , b[j]);&lt;br /&gt;
       '''for''' j := i + 1 '''to''' (N + i) '''div''' 2 '''do'''&lt;br /&gt;
         swap(b[j], b[N - j + i + 1]);&lt;br /&gt;
       return(b[1..N]);&lt;br /&gt;
     '''end'''&lt;br /&gt;
    '''else'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
       return(null);&lt;br /&gt;
     '''end;'''&lt;br /&gt;
   '''end;'''&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;
== Специализация алгоритма для генерации [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 следующего сочетания] ==&lt;br /&gt;
&lt;br /&gt;
* Добавим в конец массива с сочетанием N+1 – максимальный элемент.&lt;br /&gt;
* Пойдём справа налево. Будем искать номер элемента, который отличается от предыдущего на 2.&lt;br /&gt;
* Увеличим найденный элемент на 1, и допишем в конец минимально возможный хвост, если такого элемента нет – на вход было дано последнее сочетание.&lt;br /&gt;
 '''function''' nextChoose(var a:array[1..k] of integer): array[1..k] of integer; // n,k - параметры сочетания.&lt;br /&gt;
  '''var''' &lt;br /&gt;
   i,j : '''integer;'''&lt;br /&gt;
   b:array[1..k+1] of '''integer;'''&lt;br /&gt;
  '''begin'''&lt;br /&gt;
   '''for''' i := 1 '''to''' k '''do'''&lt;br /&gt;
    b[i]:=a[i];&lt;br /&gt;
   b[k + 1] := n + 1;&lt;br /&gt;
   i := n;&lt;br /&gt;
   '''while''' (i &amp;gt; 0) '''and''' ((b[i + 1] - b[i]) &amp;lt; 2) '''do'''&lt;br /&gt;
     i := i - 1;&lt;br /&gt;
   '''if''' i &amp;gt; 0 '''then'''&lt;br /&gt;
    '''begin'''&lt;br /&gt;
      b[i] := b[i] + 1;&lt;br /&gt;
      '''for''' j := i + 1 '''to''' k '''do'''&lt;br /&gt;
       b[j] := b[j - 1] + 1;&lt;br /&gt;
      '''for''' i := 1 '''to''' k '''do'''&lt;br /&gt;
       a[i] := b[i];&lt;br /&gt;
      return(a[1..k]);&lt;br /&gt;
    '''end'''&lt;br /&gt;
   '''else'''&lt;br /&gt;
    return(null);&lt;br /&gt;
  '''end;'''&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;
== Специализация алгоритма для генерации следующего [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 разбиения на слагаемые] ==&lt;br /&gt;
Рассматриваемый алгоритм находит следующее разбиение на слагаемые, при этом разбиение упорядоченно по возрастанию.&lt;br /&gt;
* Увеличим предпоследнее слагаемое на 1, уменьшим последнее слагаемое на 1.&lt;br /&gt;
** Если предпоследнее слагаемое стало больше последнего, то увеличиваем предпоследнее слагаемое на величину последнего.&lt;br /&gt;
** Если предпоследнее слагаемое меньше последнего, то разбиваем последнее слагаемое &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;
 // индексация списка идёт от 1&lt;br /&gt;
 // b – список, содержащий разбиение данного числа, length – его размер.&lt;br /&gt;
 '''function''' nextPartition(var b: list&amp;lt;int&amp;gt;): list&amp;lt;int&amp;gt;;&lt;br /&gt;
  '''var''' i : '''integer;'''&lt;br /&gt;
   '''begin'''   &lt;br /&gt;
    b[b.size] := b[b.size] - 1;&lt;br /&gt;
    b[b.size - 1] := b[b.size - 1] + 1;&lt;br /&gt;
    '''if''' b[b.size - 1] &amp;gt; b[b.size] '''then'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
       b[b.size - 1] := b[b.size - 1] + b[b.size];&lt;br /&gt;
       b.pop();&lt;br /&gt;
     '''end'''&lt;br /&gt;
    '''else'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
      '''while''' b[b.size - 1] * 2 &amp;lt;= b[b.size] '''do'''&lt;br /&gt;
       '''begin'''&lt;br /&gt;
        b.add(b[b.size] - b[b.size - 1]);&lt;br /&gt;
        b[b.size - 1] := b[b.size - 2];&lt;br /&gt;
       '''end;'''&lt;br /&gt;
     '''end;'''&lt;br /&gt;
    '''return''' b;&lt;br /&gt;
   '''end;'''&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 пока оно не станет &amp;lt;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;
== Специализация алгоритма для генерации следующего [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 разбиения на подмножества] ==&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;
** Заменить рассматриваемый элемент уже удаленным. Из всех подходящих элементов выбираем минимальный. '''Важное замечание''': мы не можем заменить 1ый элемент подмножества, мы можем только удалить его.&lt;br /&gt;
** Дополнить рассматриваемое подмножество уже удаленным элементом. Из всех подходящих элементов выбираем минимальный.&lt;br /&gt;
* Допишем лексикографически минимальный хвост подмножеств из оставшихся элементов.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 '''function''' nextSetPartition(a:list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;):list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;;&lt;br /&gt;
  // индексация списка идет от 0&lt;br /&gt;
  // a - список, содержащий подмножества&lt;br /&gt;
  // used - список, в котором мы храним удаленные элементы&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[used.size] &amp;gt; a[i][a[i].size] '''then'''   //если можем добавить в конец подмножества элемент из used&lt;br /&gt;
          a[i].add(used[used.size]);   //добавляем&lt;br /&gt;
          '''break'''&lt;br /&gt;
      '''for''' j = a[i].size - 1 '''downto''' 0&lt;br /&gt;
          '''if''' (j &amp;lt;&amp;gt; 1) and used[used.size] &amp;gt; a[i][j] '''then'''   //если можем заменить элемент, другим элементом из списка used &lt;br /&gt;
             a[i][j] = used[used.size];   //заменяем&lt;br /&gt;
             fl = ''true''&lt;br /&gt;
             '''break'''&lt;br /&gt;
          used.add(a[i][j]);&lt;br /&gt;
          a[i].pop(j);   // удаляем j элемент i подмножества и добавляем его в список&lt;br /&gt;
      '''if''' (fl) '''break'''&lt;br /&gt;
  // далее выведем все получившиеся подмножества&lt;br /&gt;
  sort(used)&lt;br /&gt;
  '''for''' i = 0 '''to''' used.size - 1&lt;br /&gt;
     a.add(used[i]);        // добавляем лексикографически минимальных хвост&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;
* [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>91.122.22.64</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=35096</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=35096"/>
				<updated>2014-01-04T21:38:43Z</updated>
		
		<summary type="html">&lt;p&gt;91.122.22.64: /* Специализация алгоритма для генерации следующего разбиения на подмножества */&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;
== Специализация алгоритма для генерации следующего [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 битового вектора] ==&lt;br /&gt;
* Находим минимальный суффикс, в котором есть 0, его можно увеличить, не меняя оставшейся части&lt;br /&gt;
* Вместо 0 записываем 1 &lt;br /&gt;
* Дописываем минимально возможный хвост из нулей&lt;br /&gt;
     '''function''' nextVector(a:array[1..n] of byte):array[1..n] of byte; // n - длина вектора&lt;br /&gt;
      '''for''' i = n '''downto''' 1&lt;br /&gt;
       '''if''' a[i] == 0&lt;br /&gt;
        a[i] = 1&lt;br /&gt;
        '''for''' j = i + 1 to n&lt;br /&gt;
         a[j] = 0&lt;br /&gt;
         '''break'''&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||style=&amp;quot;background:#FFCC00&amp;quot;|0||1||1||исходный битовый вектор&lt;br /&gt;
|-&lt;br /&gt;
| || ||^|| || ||находим элемент 0 (самый правый)&lt;br /&gt;
|-&lt;br /&gt;
|0||1||style=&amp;quot;background:#FFCC00&amp;quot;|1||1||1||меняем его на 1&lt;br /&gt;
|-&lt;br /&gt;
|0||1||1||style=&amp;quot;background:#FFCC00&amp;quot;|0||style=&amp;quot;background:#FFCC00&amp;quot;|0||меняем элементы правее на нули&lt;br /&gt;
|-&lt;br /&gt;
|'''0'''||'''1'''||'''1'''||'''0'''||'''0'''||следующий битовый вектор&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Специализация алгоритма для генерации [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 следующей перестановки] ==&lt;br /&gt;
* Двигаясь справа налево, находим элемент, нарушающий убывающую последовательность (в обычном порядке, слева направо, см. пример)&lt;br /&gt;
* Меняем его с минимальным элементом, большим нашего, стоящим правее&lt;br /&gt;
* Перевернем правую часть&lt;br /&gt;
&lt;br /&gt;
  '''function''' nextPermutation(a:array[1..n] of integer):array[1..n] of integer; // n - длина перестановки&lt;br /&gt;
   '''for''' i = n - 1 '''downto''' 1&lt;br /&gt;
       '''if''' a[i] &amp;lt; a[i + 1]&lt;br /&gt;
           '''for''' j = i + 1 '''to''' n&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[j])&lt;br /&gt;
           reverse(a[i + 1]..a[n])&lt;br /&gt;
           '''break'''&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;
|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;
== Специализация алгоритма для генерации следующей [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 мультиперестановки] ==&lt;br /&gt;
* Двигаясь справа налево, находим элемент, нарушающий убывающую последовательность (в обычном порядке, слева направо, см. пример).&lt;br /&gt;
* Меняем его с минимальным элементом, большим нашего, стоящим правее.&lt;br /&gt;
* Переворачиваем правую часть.&lt;br /&gt;
 '''function''' nextMultiperm(var b:array[1..N] of integer): array[1..N] of integer;&lt;br /&gt;
   '''var''' i , j : '''integer''';&lt;br /&gt;
   '''begin'''&lt;br /&gt;
    i := N - 1;&lt;br /&gt;
    '''while''' (i &amp;gt; 0) '''and''' (b[i] &amp;gt;= b[i + 1]) '''do'''&lt;br /&gt;
     dec(i);&lt;br /&gt;
    '''if''' i &amp;gt; 0 '''then'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
       j := i + 1;&lt;br /&gt;
       '''while''' (j &amp;lt; N) '''and''' (b[j + 1] &amp;gt; b[i]) '''do'''&lt;br /&gt;
         inc(j);&lt;br /&gt;
       swap(b[i] , b[j]);&lt;br /&gt;
       '''for''' j := i + 1 '''to''' (N + i) '''div''' 2 '''do'''&lt;br /&gt;
         swap(b[j], b[N - j + i + 1]);&lt;br /&gt;
       return(b[1..N]);&lt;br /&gt;
     '''end'''&lt;br /&gt;
    '''else'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
       return(null);&lt;br /&gt;
     '''end;'''&lt;br /&gt;
   '''end;'''&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;
== Специализация алгоритма для генерации [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 следующего сочетания] ==&lt;br /&gt;
&lt;br /&gt;
* Добавим в конец массива с сочетанием N+1 – максимальный элемент.&lt;br /&gt;
* Пойдём справа налево. Будем искать номер элемента, который отличается от предыдущего на 2.&lt;br /&gt;
* Увеличим найденный элемент на 1, и допишем в конец минимально возможный хвост, если такого элемента нет – на вход было дано последнее сочетание.&lt;br /&gt;
 '''function''' nextChoose(var a:array[1..k] of integer): array[1..k] of integer; // n,k - параметры сочетания.&lt;br /&gt;
  '''var''' &lt;br /&gt;
   i,j : '''integer;'''&lt;br /&gt;
   b:array[1..k+1] of '''integer;'''&lt;br /&gt;
  '''begin'''&lt;br /&gt;
   '''for''' i := 1 '''to''' k '''do'''&lt;br /&gt;
    b[i]:=a[i];&lt;br /&gt;
   b[k + 1] := n + 1;&lt;br /&gt;
   i := n;&lt;br /&gt;
   '''while''' (i &amp;gt; 0) '''and''' ((b[i + 1] - b[i]) &amp;lt; 2) '''do'''&lt;br /&gt;
     i := i - 1;&lt;br /&gt;
   '''if''' i &amp;gt; 0 '''then'''&lt;br /&gt;
    '''begin'''&lt;br /&gt;
      b[i] := b[i] + 1;&lt;br /&gt;
      '''for''' j := i + 1 '''to''' k '''do'''&lt;br /&gt;
       b[j] := b[j - 1] + 1;&lt;br /&gt;
      '''for''' i := 1 '''to''' k '''do'''&lt;br /&gt;
       a[i] := b[i];&lt;br /&gt;
      return(a[1..k]);&lt;br /&gt;
    '''end'''&lt;br /&gt;
   '''else'''&lt;br /&gt;
    return(null);&lt;br /&gt;
  '''end;'''&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;
== Специализация алгоритма для генерации следующего [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 разбиения на слагаемые] ==&lt;br /&gt;
Рассматриваемый алгоритм находит следующее разбиение на слагаемые, при этом разбиение упорядоченно по возрастанию.&lt;br /&gt;
* Увеличим предпоследнее слагаемое на 1, уменьшим последнее слагаемое на 1.&lt;br /&gt;
** Если предпоследнее слагаемое стало больше последнего, то увеличиваем предпоследнее слагаемое на величину последнего.&lt;br /&gt;
** Если предпоследнее слагаемое меньше последнего, то разбиваем последнее слагаемое &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;
 // b – список, содержащий разбиение данного числа, length – его размер.&lt;br /&gt;
 '''function''' nextPartition(var b: list&amp;lt;int&amp;gt;): list&amp;lt;int&amp;gt;;&lt;br /&gt;
  '''var''' i : '''integer;'''&lt;br /&gt;
   '''begin'''   &lt;br /&gt;
    b[b.size] := b[b.size] - 1;&lt;br /&gt;
    b[b.size - 1] := b[b.size - 1] + 1;&lt;br /&gt;
    '''if''' b[b.size - 1] &amp;gt; b[b.size] '''then'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
       b[b.size - 1] := b[b.size - 1] + b[b.size];&lt;br /&gt;
       b.pop();&lt;br /&gt;
     '''end'''&lt;br /&gt;
    '''else'''&lt;br /&gt;
     '''begin'''&lt;br /&gt;
      '''while''' b[b.size - 1] * 2 &amp;lt;= b[b.size] '''do'''&lt;br /&gt;
       '''begin'''&lt;br /&gt;
        b.add(b[b.size] - b[b.size - 1]);&lt;br /&gt;
        b[b.size - 1] := b[b.size - 2];&lt;br /&gt;
       '''end;'''&lt;br /&gt;
     '''end;'''&lt;br /&gt;
    '''return''' b;&lt;br /&gt;
   '''end;'''&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 пока оно не станет &amp;lt;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;
== Специализация алгоритма для генерации следующего [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D0.BA.D0.BE.D0.BC.D0.B1.D0.B8.D0.BD.D0.B0.D1.82.D0.BE.D1.80.D0.BD.D1.8B.D1.85_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2 разбиения на подмножества] ==&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;
** Заменить рассматриваемый элемент уже удаленным. Из всех подходящих элементов выбираем минимальный. '''Важное замечание''': мы не можем заменить 1ый элемент подмножества, мы можем только удалить его.&lt;br /&gt;
** Дополнить рассматриваемое подмножество уже удаленным элементом. Из всех подходящих элементов выбираем минимальный.&lt;br /&gt;
* Допишем лексикографически минимальный хвост подмножеств из оставшихся элементов.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 '''function''' nextSetPartition(a:list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;):list&amp;lt;list&amp;lt;int&amp;gt;&amp;gt;;&lt;br /&gt;
  // индексация списка идет от 0&lt;br /&gt;
  // a - список, содержащий подмножества&lt;br /&gt;
  // used - список, в котором мы храним удаленные элементы&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[used.size] &amp;gt; a[i][a[i].size] '''then'''   //если можем добавить в конец подмножества элемент из used&lt;br /&gt;
          a[i].add(used[used.size]);   //добавляем&lt;br /&gt;
          '''break'''&lt;br /&gt;
      '''for''' j = a[i].size - 1 '''downto''' 0&lt;br /&gt;
          '''if''' (j &amp;lt;&amp;gt; 1) and used[used.size] &amp;gt; a[i][j] '''then'''   //если можем заменить элемент, другим элементом из списка used &lt;br /&gt;
             a[i][j] = used[used.size];   //заменяем&lt;br /&gt;
             fl = ''true''&lt;br /&gt;
             '''break'''&lt;br /&gt;
          used.add(a[i][j]);&lt;br /&gt;
          a[i].pop(j);   // удаляем j элемент i подмножества и добавляем его в список&lt;br /&gt;
      '''if''' (fl) '''break'''&lt;br /&gt;
  // далее выведем все получившиеся подмножества&lt;br /&gt;
  sort(used)&lt;br /&gt;
  '''for''' i = 0 '''to''' used.size - 1&lt;br /&gt;
     a.add(used[i]);        // добавляем лексикографически минимальных хвост&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;
* [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>91.122.22.64</name></author>	</entry>

	</feed>