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

C++ Discussion :

Combinaison de k valeurs parmi n


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Inscrit en
    Février 2011
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 188
    Par défaut Combinaison de k valeurs parmi n
    Bonjour,

    le code suivant permet de calculer la combinaison de k valeurs parmi n. Pour certaines valeurs de n et q, ce code me donne des résultats erronés. J'aime savoir ou résiste le problème. Et si vous pouvez me donner une autre proposition, je serais reconnaissant.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    float MI::combinaison(int n,int q) //la Combinaison de q éléments parmi n
    {
        float comb;
        if(n==q)
        {
            return 1;
        }
        else
            if(q==1)
            {
                 return n;
            }
            else
            {
                 comb=(n/q)*combinaison(n-1,q-1);
                 return comb;
            }
    }

  2. #2
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Soit tu appliques la formule directe en simplifiant un poil pour éviter le calcul de factorielles trop grandes, soit tu calules par reccurence avec une formule correcte.

    Voir ici.

    Autre remarques. k parmi n renvoie un entier, je vois pas pourquoi ta fonction renvoie un float..
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  3. #3
    Membre très actif
    Inscrit en
    Février 2011
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 188
    Par défaut
    Citation Envoyé par Davidbrcz Voir le message
    soit tu calules par reccurence avec une formule correcte.
    cela veut dira que ma proposition est fausse??

    Citation Envoyé par Davidbrcz Voir le message
    Autre remarques. k parmi n renvoie un entier, je vois pas pourquoi ta fonction renvoie un float..
    oui c vrai, j'ai changé le type de retour en int .

  4. #4
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    cela veut dira que ma proposition est fausse??

    A toi de voir


    oui c vrai, j'ai changé le type de retour en int
    même un int c'est limite, j'aurais mis un unsigned long voir même un unsigned long long
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  5. #5
    Invité
    Invité(e)
    Par défaut
    Je suis aussi tombé là dessus:

    https://gist.github.com/jeetsukumaran/5392166

    au pire boost le fait déjà:

    http://www.boost.org/doc/libs/1_46_1..._binomial.html

  6. #6
    Membre très actif
    Inscrit en
    Février 2011
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 188
    Par défaut
    Merci pour toute ces réponses. J'ai codé ma fonction autrement mais j'ai constaté elle ne fonctionne pas pour les nombre très grand. Est ce qu'il me faut une autre bibliothèque C++ pour que je puisse réussir cette fonction?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    unsigned long long combinaison(unsigned long n, unsigned long k) {
        unsigned long i;
        unsigned long long b;
        if (0 == k || n == k) {
            return 1;
        }
        if (k > n) {
            return 0;
        }
        if (k > (n - k)) {
            k = n - k;
        }
        if (1 == k) {
            return n;
        }
        b = 1;
        for (i = 1; i <= k; ++i) {
            b *= (n - (k - i));
            if (b < 0) return -1; 
            b /= i;
        }
        return b;
    }

  7. #7
    Membre très actif
    Inscrit en
    Février 2011
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 188
    Par défaut
    Je tombe sur http://www.boost.org/doc/libs/1_46_1..._binomial.html donc je me dirige vers l'utilisation des bibliothèques Boost pour résoudre ce problème. Est ce je suis sur le bon chemin?

  8. #8
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Normal que ta fonction ne marche plus pour des nombres grand.
    Le coefficient binomial ca grandit vite et tu dépasse rapidement la capacité d'un int. Passer sur un (unsigned) long (ou même (unsigned) long long) ne fait que déporter le soucis.

    A un moment tu tombes forcement au delà de la capacité maximale du type.

    Boost est bien car il t'assure un algorithme correct et compatible (avec les template) avec n'importe quel type du moment qu'il satisfasse des conditions basiques.

    Ca permet (e toute logique), une utilisation avec des bibliothèques de précision arbitraire telles que GMP.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Combinaisons à 6 chiffres possibles parmi 20 nombres
    Par djbebop dans le forum Algorithmes et structures de données
    Réponses: 10
    Dernier message: 14/05/2011, 14h46
  2. Réponses: 2
    Dernier message: 17/10/2008, 18h17
  3. Récupérer une seule valeur parmi plusieurs
    Par geraldgg dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 11/05/2007, 10h26
  4. [XSLT]Recuperer une valeur parmis une liste. (tri)
    Par Asaturne dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 16/06/2006, 17h27
  5. Réponses: 2
    Dernier message: 22/07/2002, 18h02

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