Découvrez les combinaisons de nombres d'un ensemble d'ajouter jusqu'à un total de

J'ai été chargé d'aider certains comptables résoudre un problème commun, ils ont donné une liste de transactions et un dépôt total, les transactions qui font partie de la caution? Par exemple, dire que j'ai cette liste de nombres:

1.00
2.50
3.75
8.00

Et je sais que mon total de la caution est 10.50, je peux facilement voir qu'il est fait de la 8.00 et 2.50 transaction. Toutefois, étant donné une centaine de transactions et un dépôt de garantie en millions de dollars, il devient rapidement beaucoup plus difficile.

Dans les tests de force brute solution (qui prend beaucoup trop de temps à être pratique), j'avais deux questions:

  1. À une liste d'environ 60 numéros, il semble trouver une douzaine ou plus de combinaisons pour n'importe quel montant raisonnable. Je m'attendais à une combinaison unique de satisfaire ma totale, ou peut-être un peu de possibilités, mais il semble toujours être une tonne de combinaisons. Est-il un math principe qui explique pourquoi il en est? Il semble que, étant donné une collection de nombres aléatoires de même une taille moyenne, vous pouvez trouver une multitude de combinaisons qui ajoute jusqu'à juste au sujet de tout montant total que vous souhaitez.
  2. J'ai construit une force brute solution au problème, mais c'est de O(n!), et grandit vite hors de contrôle. Outre l'évident raccourcis (à l'exclusion de nombre plus grand que le total d'eux-mêmes), il est un moyen de raccourcir le temps de calculer ce?

De détails sur ma super lent) solution:

La liste des montants détail est trié du plus grand au plus petit, puis le processus suivant s'exécute de manière récursive:

  • Prendre l'élément suivant dans la liste et voir si de l'ajouter à votre total en cours d'exécution rend votre total de correspondre à la cible. Si elle le fait, mettre de côté la chaîne actuelle, comme un match. Si il tombe à court de votre cible, de l'ajouter à votre total en cours d'exécution, le retirer de la liste des montants détail, et ensuite appeler ce processus à nouveau

De cette manière, il exclut le plus grand nombre rapidement, la coupe de la liste vers le bas pour seulement le nombre de besoins à prendre en compte. Cependant, il est toujours n! et les grandes listes semblent ne jamais se terminer, donc je suis intéressé par tous les raccourcis que je pourrais être en mesure de prendre de la vitesse, je pense que même coupe 1 nombre de la liste permettrait de réduire le temps de calcul dans la moitié.

Merci pour votre aide!

Regardez dans le sac à Dos de Problème. Il y aura plusieurs solutions, sauf si vous avez plus d'informations pour commencer.
double a 64 bits, et vos chiffres sont issus d'un petit sous-ensemble de cette, de sorte qu'il n'est pas vraiment une surprise que à 60 éléments il existe de nombreuses solutions, il y en a 2^60 sous-ensembles dont les sommes de la carte dans le double.
n! est faux, c'est 2^n.

OriginalL'auteur SqlRyan | 2010-10-21