¿Existe un algoritmo para generar todas las combinaciones de manera ordenada?

Jeremy, como muchas veces en esos asuntos hay varias formas de hacer el trabajo. Robert ha dado una buena manera de usar Python.

Una alternativa usando C ++ es según el código a continuación. ¿Asumo que quieres combinaciones sin repetición? Como sabrá con las combinaciones, debe especificar un índice más bajo. El índice superior se especifica a sí mismo.

char [] inputSet = {‘A’, ‘B’, ‘C’, ‘D’};

Combinaciones combinaciones = nuevas Combinaciones (inputSet, 3);
string cformat = “Combinaciones de {{ABCD}} elija 3: size = {0}”;
Console.WriteLine (String.Format (cformat, combinaciones.Count));
foreach (IList c en combinaciones) {
Console.WriteLine (String.Format (“{{{0} {1} {2}}}”, c [0], c [1], c [2]));
}

Variaciones variaciones = nuevas Variaciones (inputSet, 2);
string vformat = “Variaciones de {{ABCD}} elija 2: size = {0}”;
Console.WriteLine (String.Format (vformat, variaciones.Count));
foreach (IList v en variaciones) {
Console.WriteLine (String.Format (“{{{0} {1}}}”, v [0], v [1]));
}
Generará:
Ocultar código de copia
Combinaciones de {ABCD} elegir 3: tamaño = 4
{A B C}
{ABD}
{ACD}
{BCD}
Variaciones de {ABCD} elegir 2: tamaño = 12
{AB}
{C.A}
{ANUNCIO}
{LICENCIADO EN LETRAS}
{CALIFORNIA}
{DA}
{ANTES DE CRISTO}
{BD}
{CB}
{DB}
{DISCOS COMPACTOS}
{CORRIENTE CONTINUA}

Python itertools tiene implementaciones ordenadas: 9.7. itertools – Funciones que crean iteradores para un bucle eficiente – Documentación de Python 2.7.10rc0

Están ordenados Otra cosa que generalmente puede hacer es iterar a través de todos los enteros de n bits y ver cuáles tienen bits r. Si el bit i-ésimo es 1, entonces se elige el i-ésimo de los n elementos.

Usando un número entero para representar un conjunto, puede ver la configuración en una matriz cuyo número entero es un índice, en O (1). También tiene operadores bit a bit para operaciones de conjuntos como unión, resta, etc.

Para su problema, no necesita asignar un número entero a una combinación; puede generar las combinaciones por separado, por ejemplo, con itertools como escribe Robert Edward King.

Sin embargo, si desea asignar un número entero a una combinación, hay una manera fácil de hacerlo. Si i> ((n-1) Cr), entonces la combinación contiene el enésimo bit; iterar con (i- (n-1) Cr), (n-1) y (r-1). De lo contrario, no contiene el enésimo bit; iterar con i, (n-1) y r. Cuando n = 0, afirma que r == 0 e i == 1, y listo. (Para la indexación basada en 0, cambie a i == 0 y “if i> = …” arriba).

Esto genera las combinaciones en orden creciente.

Creé este algoritmo para generar combinaciones de lotería a partir de un conjunto favorito de números, y escribí un programa Pascal / Delphi hace muchos años. Se puede usar para enumerar cualquier tipo de combinaciones cuando se usan los tipos de variables adecuados en su programa real.

Introducción
=========
Este es un algoritmo general para generar las combinaciones cuando x elementos se eligen entre y elementos. El número de combinaciones viene dado por la fórmula:
y! / ((yx)! x!), donde! denota factorial. Este número se calcula fácilmente.
El problema que surge es enumerar las combinaciones reales. Como ejemplo:

¿De cuántas maneras podemos elegir 2 artículos de 3 artículos? De la fórmula:
3! / ((3-2)! 2!) = 3 * 2 * 1 / ((1) * (2 * 1) = 6/2 = 3.

Ahora enumera las combinaciones. Digamos que los elementos son A, B y C. Luego, por
inspección, la lista de opciones sería: [A, B], [A, C], [B, C]. Suficientemente fácil,
en este caso. Pero, ¿y si tuviéramos que elegir 6 artículos de 9 artículos?
Nuevamente, el número de combinaciones se puede calcular a partir de la fórmula:
9! / ((9-6)! 6!), Que se puede simplificar para:
9 * 8 * 7/6 (¡ya que 9! = 9 * 8 * 7 * 6 !, y (9-6)! = 3! = 6.) = 84.

Ahora, ¿cómo generamos las 84 combinaciones? La inspección sería muy tediosa aquí. De ahí la necesidad de un algoritmo general para resolver este problema.

Generando las combinaciones cuando x elementos se eligen de y elementos
=============================================
1. Defina una matriz de almacenamiento (AR) y almacene los elementos y.

2. Defina x variables para los contadores de bucles (requerirá bucles anidados de 1 a x)
(p. ej., x = 6 podría tener variables de contador de bucle i, j, k, l, m, n)

3. Calcule el número de iteraciones necesarias para el primer bucle (más externo) como:
(yx) +1. (p. ej., 6 de 9 requeriría (9-6) +1 = 4 iteraciones del primer bucle).

4. La segunda variable del ciclo iterará de 2 (1 + 1) a (yx) +2.

;
;
;
5. La variable del bucle xth iterará (bucle más interno) a partir del valor de
la (x-1) th variable +1 a y. (por ejemplo, para x = 6, y = 9 y contadores
i, j, k, l, m, n. La variable de contador x, n iteraría desde el valor
de m + 1 a 9 para el bucle más interno).

6. Genere las combinaciones en el bucle más interno utilizando los valores variables como índices de matriz (AR):
AR (primer contador), AR (segundo contador), … AR (contador x).
El total de iteraciones anidadas generará combinaciones y! / ((Yx)! X!).

Un pseudocódigo para generar las combinaciones cuando se eligen 6 elementos de valores enteros entre 9 de estos elementos podría tener este aspecto:

I. Defina la matriz AR del número entero y almacene los 9 números enteros.
matriz AR [1..9] (inicializar con los 9 elementos. Por ejemplo, AR (1) = 5, AR (2) = 10, .. etc.

II Defina 6 variables de bucle y una variable de contador.
int i, j, k, l, m, n, c

III. Iterar a través de los 6 bucles anidados:
empezar
c = 0 {inicializar c a 0}
para i = 1 a 4 {recuerde 9-6 + 1 = 4} hacer
para j = i + 1 a 5 {9-6 + 2} hacer
para k = j + 1 a 6 {9-6 +3} hacer
para l = k + 1 a 7 {9-6 +4} hacer
para m = l + 1 a 8 {9-6 +5} hacer
para n = m + 1 a 9 {9-6 +6} hacer
empezar

IV. {Imprima las combinaciones en el bucle más interno:}
{Puede usar un contador, c para rastrear el número de combinaciones impresas.}
c = c +1
Imprimir (c, AR (i), AR (j), AR (k), AR (l), AR (m), AR (n))

end {iteraciones e impresiones de cada combinación numerada}

fin.