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 :

Calcule d'une combinaison


Sujet :

Algorithmes et structures de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé Avatar de ccensam
    Inscrit en
    Juillet 2005
    Messages
    128
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Juillet 2005
    Messages : 128
    Par défaut Calcule d'une combinaison
    Salut ça fais 1 semaine que j'essaye d'ecrire un programme qui calcule
    exactement et cela pour des nombres un peu grands sans depasser la limite de unsigned int.
    Quelqu'un à une bonne idée.!

  2. #2
    Expert confirmé Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Par défaut
    Bonjour,

    Pour gérer de grands entiers tels que peuvent en donner des factoriels,
    Il faut se faire son propre code ou utiliser une bibli non standard pour gérer des entiers super-longs.

    Un petit code (en dephi) qui pourrait t'interesser :
    http://www.delphiforfun.org/Programs/big_factorials.htm

    Ca te donnera les algo pour les fonctions de multiplication et division

  3. #3
    Rédacteur
    Avatar de pcaboche
    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    2 785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Singapour

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 785
    Par défaut
    Sauf erreur de ma part (n'hésitez pas à me corriger):

    1) Si n/2 =< k =< n, on a:
    1 =< n-k+1 =< k =< n

    au numérateur: n-k+1 --> n
    au dénominateur: 1 --> k

    Les nombres qui sont entre n-k+1 et k apparaissent donc à la fois au numérateur et au dénominateur, donc on peut les éliminer.

    On a alors:
    au numérateur: k --> n
    au dénominateur: 1 --> n-k+1

    Maintenant, pour éviter les dépassement de capacité, on prend un élément du numérateur, un élément du dénominateur, on en fait le quotient et ainsi de suite:
    R = k/1 * (k+1)/2 * ... * n/(n-k+1)


    2) Si 0 < k < n/2, on a:
    1 =< k =< n-k+1 =< n

    On a alors:
    au numérateur: n-k+1 --> n
    au dénominateur: 1 --> k

    Aucun élément n'apparait à la fois au numérateur et au dénominateur, mais comme toute à l'heure, on prend un élément du numérateur, un élément du dénominateur, on en fait le quotient et ainsi de suite:
    R = (n-k+1)/1 * (n-k+2)/2 * ... * n/k

    ***
    Maintenant, y a-t'il un mathématicien dans l'assemblée pour vérifier mes dires? (ça m'arrive de faire des erreurs en maths, donc j'aimerais confirmation/infirmation)
    "On en a vu poser les armes avant de se tirer une balle dans le pied..."
    -- pydévelop

    Derniers articles:

    (SQL Server) Introduction à la gestion des droits
    (UML) Souplesse et modularité grâce aux Design Patterns
    (UML) Le Pattern Etat
    Autres articles...

  4. #4
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Par défaut
    Bonjour,

    on n'utilise jamais la formule du C(n,p)!!!
    Il faut plutot utiliser le triangle de pascal. En revanche celui ci dépasse les int_max pour une valeur de n=35. Il te faut donc trouver une lib qui gère ce genre de soucis.

    Au fait, pour quelle type d'utilisation est ce ????
    Consignes aux jeunes padawans : une image vaut 1000 mots !
    - Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe, mettre les ACCENTS et les BALISES) => ECRIRE clairement et en Français tu DOIS.
    - Le côté obscur je sens dans le MP => Tous tes MPs je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
    - ton poste tu dois marquer quand la bonne réponse tu as obtenu.

  5. #5
    Expert confirmé

    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 419
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 419
    Par défaut
    outre les simplifications déja proposées
    on peut remplacer un produit par une addition de logs
    sans entrer dans des bibliothèques sur les nombres longs
    c'est facile à mettre en oeuvre

  6. #6
    Membre éprouvé Avatar de ccensam
    Inscrit en
    Juillet 2005
    Messages
    128
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Juillet 2005
    Messages : 128
    Par défaut Ma solution
    Voila ce que j'ai reussit à faire.
    Ce petit code en C permet de calculer la combinaison à condition qu'elle ne dépasse pas la capacité de long int. Et elle n'utilise que des variables entières :
    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    #include <stdio.h>
    #include <stdlib.h>
     
    void nodiv(unsigned long * , unsigned long *);
    int compar(int , int); //
    unsigned long calcul(int , int);
     
    int main(int argc , char **argv)
    {
        int n,k;
        char *ptr;
     
        printf("Ce programme calcul une combinaison k de n.\n\n");
        printf("\tDonnez n = ");
        scanf("%d",&n);
        printf("\tDonnez k = ");
        scanf("%d",&k);
        printf("La combinaison K de n = %u ",calcul(n,k));
        system("PAUSE");
        return EXIT_SUCCESS;
    }
     
    unsigned long calcul(int n , int k)
    {
        unsigned long p=1,ddv=1;
        int i;
     
        if(n==0 || k==0) return 1;
        for(i=1;i<=compar(n-k,k);i++) // avancement jusqu'à le min de (n-k) e k
        {
                         if(p%i==0)
                         {
                                   p=(p/i)*(n-i+1);
                                   nodiv(&p,&ddv);
                         }
                         else if ((n-i+1)%i==0)
                         {
                                   p*=((n-i+1)/i);
                                   nodiv(&p,&ddv);
                         }
                         else
                         {
                                   p*=(n-i+1);
                                   ddv *=i;
                       /* On garde la valeur de i dans ddv parce qu'il ne divise ni p
                                      ni (n+1-i).
                      La division sur ddv se fait dans la fonction nodiv(int *,int *)
                                   */
     
                         }
        }
        return p;
    }
     
    int compar(int a , int b)
    {
         return (a<b? a:b);
         /* renvoie  le min entre (n-k) et k
            Cela pour diminuer le nombres de calculs parcequ'on a une symetrie.
            par exemple les deux couples (50,48) et (50,2) donnent le meme resultat.
         */
    }
     
    void nodiv(unsigned long *p , unsigned long *ddv)
    {
         if(*p%*ddv==0)
         {
                       *p/=*ddv;
                       *ddv = 1;
         }
    }
    Vous pouvez poser des questions.

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

Discussions similaires

  1. [Algo] Trouver un arrangement ou une combinaison d'éléments
    Par Morvan Mikael dans le forum Algorithmes et structures de données
    Réponses: 16
    Dernier message: 20/04/2013, 11h46
  2. Calcul sur une région répété...
    Par Angeldu74 dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 06/06/2005, 08h00
  3. [VCL] Comment détecter une combinaison de touches ?
    Par micatmidog dans le forum Composants VCL
    Réponses: 3
    Dernier message: 23/01/2005, 14h19
  4. Recuperer un champ calculé dans une variable....
    Par vijeo dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 21/12/2004, 14h57
  5. calcul dans une requête
    Par blaz dans le forum Langage SQL
    Réponses: 8
    Dernier message: 22/12/2003, 10h31

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