IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Algorithmes et structures de données Discussion :

Combinaison de nombres dont la somme est inférieure à une valeur


Sujet :

Algorithmes et structures de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    développeur
    Inscrit en
    Octobre 2004
    Messages
    480
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : développeur
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Octobre 2004
    Messages : 480
    Par défaut Combinaison de nombres dont la somme est inférieure à une valeur
    Bonjour,

    Soit une somme S = 270.
    Soit 9 nombres qui varient de 0 à S.
    Quelle est la liste des 9 nombres dont la somme est <= S ?

    Par exemple
    270 0 0 0 0 0 0 0 0
    269 0 0 0 0 0 0 0 0
    269 1 0 0 0 0 0 0 0
    269 0 1 0 0 0 0 0 0
    ...
    268 0 0 0 0 0 0 0 0
    ....
    268 1 1 0 0 0 0 0 0
    268 1 0 1 0 0 0 0 0
    ....
    268 0 1 1 0 0 0 0 0
    268 0 1 0 1 0 0 0 0
    .....
    15 0 0 0 0 0 0 0
    36 0 25 0 18 0 0 0 0
    .....
    0 0 0 0 269 0 0 0 0
    0 0 0 0 269 1 0 0 0
    ....

    La position du nombre dans la ligne est à prendre en compte.
    269 1 0 0 0 0 0 0 0
    0 0 0 0 269 1 0 0 0
    sont deux combinaisons qui doivent être conservées.

    Pour l'instant, j'ai fait une boucle récursive qui génèrent toutes les combinaisons des 9 nombres.
    Je teste à chaque fois leur somme.
    Si <= S, je garde.

    Mais ça fait 270⁹ combinaisons à tester......

    Y aurait-il plus rapide pour trouver les combinaisons qui satisfont à la somme sans tester toutes les combinaisons ?

  2. #2
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 287
    Par défaut
    Bonjour

    Chaque nombre est ou n'est pas dans la combinaison finale. Donc 2 cas possibles pour chaque 9 nombres, soit 29=512 valeurs possibles.

    Vu l'énoncé, je les écrirais tous (les 512) et je supprimerais ceux qui dépassent S, en prenant ceux qui ont 9 nombres puis ceux qui ont 8 nombres (sous-ensemble du précédent), puis ceux qui ont 7 nombres (sous-ensemble du précédent), puis 6, puis 5, puis 4, etc

  3. #3
    Membre éclairé
    Homme Profil pro
    développeur
    Inscrit en
    Octobre 2004
    Messages
    480
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : développeur
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Octobre 2004
    Messages : 480
    Par défaut
    Chacun des 9 nombres peut valoir entre 0 et 270.
    Et on peut avoir plusieurs fois le même nombre sur chaque ligne.

    J'ai compété mon premier post :
    La position du nombre dans la ligne est à prendre en compte.
    269 1 0 0 0 0 0 0 0
    0 0 0 0 269 1 0 0 0
    sont deux combinaisons qui doivent être conservées.

  4. #4
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Par défaut
    Bonjour,

    Y aurait-il plus rapide pour trouver les combinaisons qui satisfont à la somme sans tester toutes les combinaisons ?
    Comme on le voit dans ton exemple, on s'aperçoit assez vitre qu'on peut décomposer la liste.

    Si on appelle SubsetSum(N,S) les listes de N nombres dont la somme est égale à S, alors

    SubsetSum(9,270) = {SubsetSum(1,270) X SubsetSum(8, 0)}, {SubsetSum(1,269) X SubsetSum(8, 1)}, {SubsetSum(1,268) X SubsetSum(8, 2)}, ...

    Ou, d'une manière générale

    SubsetSum(N,S) = SubsetSum(N-i,S-k) X SubsetSum(i,k) pour k parcourant [0,S], et i une valeur arbitraire dans [0,N]

    avec
    SubsetSum(0,a) = vide
    SubsetSum(1,a) = {a}


    Ca nous fait donc un tableau de S*N listes à remplir par récursion, puis un algo assez simple pour "piocher" les bonnes cases du tableau.
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  5. #5
    Membre éclairé
    Homme Profil pro
    développeur
    Inscrit en
    Octobre 2004
    Messages
    480
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : développeur
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Octobre 2004
    Messages : 480
    Par défaut
    Citation Envoyé par pseudocode Voir le message
    Si on appelle SubsetSum(N,S) les listes de N nombres dont la somme est égale à S
    J'avais bien regardé du côté de l'algorithme SubsetSum, mais il ne fait que pour =.
    Je cherche <=

    Citation Envoyé par pseudocode Voir le message
    SubsetSum(N,S) = SubsetSum(N-i,S-k) X SubsetSum(i,k)
    Comment traduire X ? C'est un produit de matrices ?

    Citation Envoyé par pseudocode Voir le message
    un tableau de S*N listes à remplir
    J'ai déjà fait un essai avec ma méthode avec les 9 nombres valant 0 ou 30, j'obtiens 48 556 combinaisons à retenir.

    0 0 0 0 0 0 0 0 30
    0 0 0 0 0 0 0 30 0
    0 0 0 0 0 0 0 30 30
    0 0 0 0 0 0 30 0 0
    0 0 0 0 0 0 30 0 30
    0 0 0 0 0 0 30 30 0
    0 0 0 0 0 0 30 30 30
    ......
    30 30 30 30 30 30 30 30 30


    Ca ne représente qu'une partie de ce dont j'ai besoin ( rappel : les 9 nombres valent entre 0 et 270).
    On est donc loin des S*N = 270*9 = 2430.

  6. #6
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Par défaut
    Citation Envoyé par senacle Voir le message
    J'avais bien regardé du côté de l'algorithme SubsetSum, mais il ne fait que pour =.
    Je cherche <=
    Si tu as une solution pour la somme exacte, les solutions de ton problème ont forcément des coordonnées inférieures:

    Solution Somme=270 --> (200,60,10,0,0,0,0,0,0)

    Solution Somme<=270 --> ([0-200],[0-60],[0-10],0,0,0,0,0,0)

    Comment traduire X ? C'est un produit de matrices ?
    Un produit cartésien: {a,b} x {1,2} = (a,1), (a,2), (b,1), (b,2)

    Ca ne représente qu'une partie de ce dont j'ai besoin ( rappel : les 9 nombres valent entre 0 et 270).
    On est donc loin des S*N = 270*9 = 2430.
    Aucune méthode ne va diminuer le nombre de solutions à ton problème.
    Là je proposais juste de construire les solutions finales en concaténant les solutions intermédiaires pour que ce soit plus rapide.
    Mais le nombre de solution
    de solutions à ton problème reste de toutes façons très grand (cf. "Partition d'un entier" sur wikipedia).
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  7. #7
    Membre éclairé
    Homme Profil pro
    développeur
    Inscrit en
    Octobre 2004
    Messages
    480
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : développeur
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Octobre 2004
    Messages : 480
    Par défaut
    Citation Envoyé par pseudocode Voir le message
    Si tu as une solution pour la somme exacte, les solutions de ton problème ont forcément des coordonnées inférieures:

    Solution Somme=270 --> (200,60,10,0,0,0,0,0,0)

    Solution Somme<=270 --> ([0-200],[0-60],[0-10],0,0,0,0,0,0)
    OK, compris.


    Je vais essayer de créer le code en php.


    Citation Envoyé par pseudocode Voir le message
    (cf. "Partition d'un entier" sur wikipedia).
    En fait, ce serait plutôt la composition d'un entier dans mon cas : l'ordre est important.
    https://fr.wikipedia.org/wiki/Compos...ombinatoire%29

Discussions similaires

  1. Défi N°1 : Génération des ensembles de nombre dont la somme est identique
    Par millie dans le forum Défis langages fonctionnels
    Réponses: 143
    Dernier message: 08/02/2018, 18h45
  2. RSYNC synchronisation des fichiers dont la date est inférieure à 1 an
    Par modus57 dans le forum Shell et commandes GNU
    Réponses: 3
    Dernier message: 06/03/2014, 09h32
  3. Lignes dont la date est inférieure à 2 jours
    Par cedrick21 dans le forum Langage SQL
    Réponses: 4
    Dernier message: 12/10/2011, 15h37
  4. Réponses: 6
    Dernier message: 12/01/2010, 16h44
  5. Rechercher les nombres dont la somme est donnée
    Par TMuet dans le forum Intelligence artificielle
    Réponses: 2
    Dernier message: 17/08/2009, 17h17

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo