Trouver la bonne série de nombres pour un résultat donné

Trouver la bonne série de nombres pour un résultat donné - VB/VBA/VBS - Programmation

Marsh Posté le 12-11-2013 à 10:03:12    

Salut à tous !
Mon problème est simple... ou non... c'est selon.  :D  
Bref, je vous présente ce que j'aimerais faire en langage VBA... à moins qu'Excel propose une formule "miracle"...
 
Voici les éléments de mon énigme :
  - j'ai une série de nombre dans une colonne : 16 nombres tous différents
  - je connais le résultat de la somme d'un certain nombre d'entre eux ; ça peut être 2 nombres, 3, 4 ou plus... mais tous puisque j'aurais déjà trouvé  ;)  
 
Alors donc, je cherche le moyen - à part tatonner sans cesse - pour trouver cette série de nombres.
 
Merci pour vos idées.
 
scaryfan


---------------
iMac 4Ghz (fin 2015) RAM 16Go SSD 256Go SSD 2To
Reply

Marsh Posté le 12-11-2013 à 10:03:12   

Reply

Marsh Posté le 12-11-2013 à 12:25:31    

 
           Bonjour,
 
           sans présentation claire & exhaustive accompagnée d'un exemple …


Message édité par Marc L le 12-11-2013 à 12:25:57
Reply

Marsh Posté le 12-11-2013 à 14:59:53    

...
 
Dans une colonne, j'ai 10 nombres :
 
45
68
95
10
5
65
42
43
58
9
 
La somme de certains de ces nombres fait 240.
 
Comment faire pour deviner les bons nombres... et je ne sais pas combien il en faut...
Simple
 
...


---------------
iMac 4Ghz (fin 2015) RAM 16Go SSD 256Go SSD 2To
Reply

Marsh Posté le 12-11-2013 à 17:10:56    

 
           Cela revient à effectuer une recherche combinatoire …
 

Reply

Marsh Posté le 12-11-2013 à 17:29:07    

Salut,
Je pense que tu peux t'inspirer de ce fichier :
http://cjoint.com/?BEushEb54QO

Reply

Marsh Posté le 13-11-2013 à 11:37:36    

 
           scaryfan, j'ai retrouvé ma procédure combinatoire spéciale VBA d'une vingtaine de lignes
           trouvant quatre solutions à ton exemple en 0,03 seconde !
           Avec 16 éléments, le nombre de combinaisons augmentant de manière factorielle, compter moins de 2 secondes …
 
           En entrée tu as défini les données dans une colonne mais le résultat tu en fais quoi ? Un simple message ?
 
           La solution consiste de comparer d'abord la somme de tous les éléments au montant désiré puis, si pas de correspondance,
           vérifier chaque combinaison de 2 éléments jusqu'à n-1 éléments parmi un total de n éléments.
 
           Simple …

Message cité 2 fois
Message édité par Marc L le 13-11-2013 à 13:59:56
Reply

Marsh Posté le 15-11-2013 à 07:01:43    

Merci à vous tous pour vos réponses.
Je vais donc plancher...  :D  ... faut bien que je m'occupe au boulot...  :sol:


---------------
iMac 4Ghz (fin 2015) RAM 16Go SSD 256Go SSD 2To
Reply

Marsh Posté le 17-11-2013 à 19:50:32    

 
           Dans le message initial, il est question d'une série de 16 nombres puis dans le suivant il n'y en a plus que 10 :
           donc l'idéal est de plancher sur une procédure fonctionnant quel que soit le nombre d'éléments à vérifier
           comme dans ma procédure et peut-être celle de takama13 …
 

Reply

Marsh Posté le 18-11-2013 à 11:48:25    

Marc L a écrit :


           La solution consiste de comparer d'abord la somme de tous les éléments au montant désiré puis, si pas de correspondance,
           vérifier chaque combinaison de 2 éléments jusqu'à n-1 éléments parmi un total de n éléments.

 

Perso, je partirai dans l'autre sens en pariant que la somme désirée est composée de peu d'éléments, même si à ce niveau on rentre directement dans le "ventre" donc on commence par n combinaisons au lieu d'une mais dans le "ventre" on a une symétrie des combinaisons possibles et du coup ça ne change rien de partir d'un côté plus qu'un autre.

 

n!/(k!*(n-k)!)

 

3 éléments : 3 3 1
4 éléments : 4 6 4 1
5 éléments : 5 10 10 5 1
6 éléments : 6 15 20 15 6 1


Message édité par MaybeEijOrNot le 18-11-2013 à 11:48:49
Reply

Marsh Posté le 18-11-2013 à 12:10:47    

 
           En fait la procédure retrouvée était à des fins comptabilo - financières
           où régulièrement la somme recherchée correspondait au total des montants …
           Donc commencer par le total évite d'effectuer toutes les combinaisons de 2 à n-1 montants !
 
           Effectivement cela ne change rien au temps de traitement quand il n'y a pas de correspondance avec le total :
           entre 0.015 et 0.032 seconde pour 10 éléments sur un ordinateur de test.
 
           Mais j'envisage une variante spéciale VBA Excel réduisant d'au moins 25% les itérations.
           Pas encore eu le temps de m'y mettre et de voir si le gain en temps est vraiment significatif,
           peut-être pas pour 10 éléments mais avec 16, à vérifier …


Message édité par Marc L le 18-11-2013 à 12:34:15
Reply

Marsh Posté le 18-11-2013 à 12:10:47   

Reply

Marsh Posté le 18-11-2013 à 13:19:19    

Une autre approche possible, c'est de passer par des algos génétiques.
Chaque "individu" est représenté par une des 0 et des 1, chaque case correspondant à un "gène", ici, l'un des nb. 1, on prend le nb dans la fonction d'éval, 0, on le prend pas. La fonction d'éval est la somme des gènes pris. L'individu est conservé si sa fonction d'éval est égale au nb recherché.
Pour générer la génération suivante, on défini 2 points de "coupure" dans les gènes (ex : après 2 ème et après le 7ème), et on prend la partie basse de l'individu qui contient les 0 et 1 (donc les gènes de 8 à 16) qu'on place en début de l'individu de la nouvelle génération, et la partie haute qu'on place à la fin de l'individu de la nouvelle génération (en gros, on donne 2 coup de ciseaux sur l'individu de la génération N, on a 3 morceaux, le morceau central reste à sa place sur l'individu de la génération N+1 et on inverse la place des 2 morceaux restants).
 
Cette méthode, sur des ensembles de données importants, donne de bons résultats. Comme toute heuristique, il faut bien adapter la taille de la population et le nb d'itérations pour être sûr d'avoir les meilleurs individus ;)
 
J'avais développé cet algo pour 2 cas :
1) plusieurs fichiers dans la somme des tailles était > la somme des CDs à graver -> fallait trouver les fichiers à prendre (donc pas tous) pour minimiser la place perdue sur chaque CD.
 
2) j'ai x tickets restos pour payer des pizzas -> trouver toutes les combinaisons de pizzas (petites ou grandes) dont la somme des prix fait exactement la somme des montants des tickets restos (ben oui, on rend pas la monnaie dessus). Ce 2ème cas est proche du pb exposé par l'auteur de ce topic ;)


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 18-11-2013 à 13:36:07    

 
           Là la représentation ne me vient pas directement à l'esprit …
 
           Sur mon idée entrevue avec une visualisation partielle des combinaisons à partir de 2 éléments pris sur 9,
           les itérations sont réduites de plus de 60% (194 itérations au lieu de 502).
           Mais c'est sur le papier, faut voir ensuite après concrétisation du code le temps gagné effectif …
 

Reply

Marsh Posté le 20-11-2013 à 08:04:17    

Takama13 a écrit :

Salut,
Je pense que tu peux t'inspirer de ce fichier :
http://cjoint.com/?BEushEb54QO


 
Bonjour takama13 !
La procédure plante avec CbxDoublons...  :(  


---------------
iMac 4Ghz (fin 2015) RAM 16Go SSD 256Go SSD 2To
Reply

Marsh Posté le 20-11-2013 à 09:45:10    

Salut,
ça ne plante pas chez moi :/

Reply

Marsh Posté le 20-11-2013 à 11:29:57    

Marc L a écrit :

En entrée tu as défini les données dans une colonne mais le résultat tu en fais quoi ? Un simple message ?


            scaryfan, avant de publier ma procédure, ce serait bien de savoir si elle correspond à ton besoin ! …


Message édité par Marc L le 20-11-2013 à 11:31:00
Reply

Marsh Posté le 20-11-2013 à 11:33:35    

:??:  
Que ce soit à la maison avec Excel Mac 2011 ou au boulot avec Excel 2010, ça ne passe pas...
 :??:


---------------
iMac 4Ghz (fin 2015) RAM 16Go SSD 256Go SSD 2To
Reply

Marsh Posté le 20-11-2013 à 13:02:45    

Excel 2010 au boulot et ça marche.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed