Algoritmo para seleccionar un número específico de elementos de un conjunto para alcanzar algún valor

Dado un conjunto de elementos n [1], n [2], n [3], .... n [x] y un número V. (Los elementos tienen sus propios valores)

Me gustaría encontrar todas las combinaciones de elementos que cumplan las siguientes condiciones:

1) Cada combinación contiene un número específico de elementos (por ejemplo: exactamente 5 elementos)

Combinación # 1: n [1], n [2], n [21], n [22], n [24]

Combinación # 2: n [1], n [2], n [12], n [15], n [33]

......

2) La suma de los valores de los elementos en combinación debe ser menor que el número V dado (por ejemplo, V = 100)

Combinación # 1: n [1] + n [2] + n [21] + n [22] + n [24] <100

Combinación # 2: n [1] + n [2] + n [12] + n [15] + n [33] <100

......

Estoy tratando de escribir un programa ac # que calcule estos elementos. Pero el lenguaje no es importante, ¡cualquier algoritmo que cumpla estas condiciones es aceptable!

Muchas Gracias

preguntado el 10 de mayo de 11 a las 13:05

¿Y cada elemento n [x] solo se puede usar una vez? -

Sí, cada elemento solo se puede usar una vez.

pregunta ampliada de [enlace] (stackoverflow.com/questions/3957227/…) -

¿Se requiere que todos los elementos sean números positivos? -

2 Respuestas

Dado que probablemente tendrá que usar la fuerza bruta de todos modos, puede resolver su problema con el siguiente enfoque:

En primer lugar, ordene su conjunto de entrada S.

Luego elimine todos los elementos de S que sean mayores que V - 4*|min| (dónde |min| es el valor absoluto del elemento más pequeño), porque de todos modos no aparecerán en ninguna de sus soluciones. Dependiendo de la especificación exacta de su problema, esta optimización puede mejorarse aún más.

Ahora genera todas las sumas de longitud C de elementos en S, comenzando con los números más pequeños posibles (recuerde que S está ordenado).

Si el resultado es menor que V, agréguelo a su conjunto de soluciones y aumente el último sumando.

De lo contrario, establezca el sumando previamente aumentado y todos los sumandos posteriores a ese en sus valores más pequeños posibles y aumente el sumando justo antes de eso.

Puede detenerse si todos los sumandos han alcanzado sus valores más altos posibles. Es posible que pueda detenerse mucho antes de eso, lo que se deja como un ejercicio para el lector debido a mi inglés descuidado.

contestado el 11 de mayo de 11 a las 15:05

gracias por el enfoque, sería mejor ver un código de muestra debido a mi inglés descuidado también :) - obertura

No estoy tan seguro, pero tal vez puedas adaptar esta idea para tener la condición de que todas las combinaciones deben tener una cierta cantidad de elementos.

http://en.wikipedia.org/wiki/Knapsack_problem

Sin embargo, se dice que el problema de la mochila tiene una complejidad de NP-completo para ser resuelto exactamente ... Eso es una mala noticia. Entonces, lo que la gente sugiere hacer es usar un algoritmo de retroceso.

Estoy seguro de que encontrarás muchos códigos en Google sobre cómo dar marcha atrás por el problema de la mochila.

espero que esto ayude

contestado el 10 de mayo de 11 a las 17:05

¿Quieres contarlos o simplemente enumerarlos? - Rob Neuhaus

Necesito exactamente elementos C (constantes), tal vez pueda usar el retroceso, pero el código de muestra podría ser útil: obertura

@Mehmet: No entiendo tu respuesta. ¿Quieres enumerar los elementos o contarlos? - tímidamente

Quiero enumerar los elementos, (todas las combinaciones posibles) - obertura

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.