SOS algorithme

Bonjour,

slt tt le monde ca fait un moment que cherche a touver un algorithme mais je arrive pas ,je sais po pourkoi ,a premier vue il doit pas etre tres dur mais moi je bogue completement ,alors c vous pourraier m'aider ou me donner juste une aide commet faire,
voila le probleme :
suppose que tu as n urnes (sac..) identique et n balles differentes et tu veut avoir tt les cas possible de distribution de ces balle sur ses urnes , exemple
c tu as 2 urnes alors tu as 2 balles ----> 2 cas :
1 cas : urnes 1 contient la balle 1 et l 'urne 2 contient la balle 2 (ou contrire )
2 cas :urne 1 contient les deux balle (c pareil que urne 2 contient les 2 balle puisque identique )

pour 3 urnes et 3 balles on a 5 cas
pour 4 on a 15 cas
pour 5 on a 40 cas

je cherche a le codé en C

pour la prtie calcul de nombre de cas j ai fait deja ca ,
moi je cherche a affecter pour chaque cas les balle et suvgarder tt les cas ,pour pour pouvoir les afficher c-a-d si je veut verifier les belle de 1 er cas il doit m afficher que j ai la belle 1 dans l 'urnes 1 et la belle 2 dans l urne 2;

pour 3 urnes et 3 balle c 5 cas •

cas 1 • U1=(balle1), U2=(balle 2), U3=(belle 3),
cas 2• U1=(1,2), U2=(3),
cas 3• U1=(1,3), U2=(2),
cas4• U1=(2,3), U2=(1),
cas 5• U1=(1,2,3),

pour ma part moi j ai consederé les cas comme des sequence alors j essyer de le faire sous forme de structure avec des place pour mettre les balles

juste pour rappel llaffecation U1=(1,2) ,U2=( ) ,U3=(3) , et pariel que U1 =( ) , S2=(1,2) ,U3=(3)
j espere ke c clair maintenant

merci d'avance pour votre aide
Configuration: Windows XP
Firefox 1.5.0.9

46 réponses

Résumé de la discussion

Le problème consiste à énumérer les partitions d'un ensemble de n balles distinctes dans des urnes identiques, et le comptage évoqué n'est pas le bon pour n=5, qui est 52. Plusieurs réponses proposent d'identifier ce problème comme l'énumération des partitions d'un ensemble et d'implémenter en C soit une approche récursive, soit une méthode fondée sur une base numérique. Des codes partagés dans la discussion montrent des solutions variées, notamment une approche avec boucles et structures pour enregistrer chaque cas, et une autre basée sur une énumération en base U^B. En outre, la discussion précise que pour n=5 le nombre exact est 52 et que certaines propositions visent à réduire la complexité, passant d'exponentielle à des méthodes plus efficaces.

Bobot (l’IA à votre service)
  1. merci tt le monde pour votre aide surtout un grand merci pur KX qui a ete d'une grand aide
    merci encore
    0
    1. Modérateur
      Ton utilisation de g* me parait compliqué, si j'ai bien compris à quoi il sert, ça doit être un compteur qui te donne le numéro de ton cas... Pourquoi ne pas utiliser une variable globale int g=0; ?

      De plus je ne comprends pas la signification du mot clé struct dans ce code :
      void Enregistrer(solution s, int M, int *g,struct squence *tabsquence ) // ici un simple affichage, modifiable à volonté

      De même qu'avec g, n'est-il pas possible de définir ta structure au début du code, et son instance tabsquence en variable globale ?
      int g=0; // variable globale
      
      struct squence={ ... };
      
      squence tabsequence; // structure globale
      
      void Enregistrer(solution s, int M)
      {
           int numtache,numachine,k,machinit;
           k=0;
           machinit=0;
      
           for (numachine=0; numachine<M; numachine++)
           {
               printf("Machine %d : ",numachine );
               for (numtache=0; numtache<nbtache; numtache++)
               { 
                  if (s[numachine][numtache]==true)
                  {
                     printf(" %d ",numtache); 
                     
                     if (numachine==machinit)
                     {
                         tabsquence[g].tabmachine[numachine].tabordo[k].numjob=numtache;
                         k++ ;
                     }
                     else machinit=numachine; // à quoi sert cette ligne ? elle parait suspecte ^^
                     
                     tabsquence[g].tabmachine[numachine].tabordo[0].numjob=numtache; // cette instruction ne devrait-elle pas être dans le else ???
                     
                     k=1; // es-tu sûr que c'est bien 1 ici ???
                  }
               }
               printf("\n");
           }
      
           g++;
           
           printf("\n");
      }
      1
      1. slt
        j essyer de faire un exemple avec la structure pour le 1 er cas ca marche
        mais pour le 2 cas il excute la boucle for (numtache=0; numtache<nbtache; numtache++) just pour numtache =0 ,et puis il s'arret ( il n'incremente pas numtache) ,
        je sais pas porkoi

        typedef Bool solution[Nm][Nm];
        //la tache numtache est dans la machine numachine si s[numtache-1][numchine-1] est vrai

        void Enregistrer(solution s, int M, int *g,struct squence *tabsquence ) // ici un simple affichage, modifiable à volonté
        {

        int numtache,numachine,k,machinit;
        k=0;
        machinit=0;

        for (numachine=0; numachine<M; numachine++)
        {
        printf("Machine %d : ",numachine );
        for (numtache=0; numtache<nbtache; numtache++){ --------------------------> ici

        if (s[numachine][numtache]==true){
        printf(" %d ",numtache);

        if (numachine==machinit){

        tabsquence[*g].tabmachine[numachine].tabordo[k].numjob=numtache;
        k++ ;
        }
        else machinit=numachine;
        tabsquence[*g].tabmachine[numachine].tabordo[0].numjob=numtache;
        k=1;
        }
        }
        printf("\n");
        }

        *g=*g+1;
        printf("\n");
        }
        0
        1. Modérateur
          Je pense pas qu'il y ait grand chose à changer dans le code 26 (hormis la conversion du C++ au C et les notations urne=machine, boule=tâche, solution=séquence)

          En rajoutant une variable globale int Cpt=0; et une structure :
          struct cas={int num_sequence; sequence s; critere_optimisation c; };

          Je dirais qu'il faudrait compléter Enregistrer(solution s; int M) à peu près comme ça :
          {
          num_sequence= ++Cpt; // numéro de séquence
          cas.s=s;
          cas.c=optimisation(s);
          }
          0
          1. il faut voir les urnes comme des machines et les boule comme des taches ou cahque tache a ces catreristiques
            la 1 er partie consiste a genere toute les possibilite s d'ffectation des tache aux machines , lalgo que tu as fait deja .
            la seconde il faut que je prend chaque sequence (cas ) avec les machine (urne) et pour chaque machine les tache que elle a traiter ,puis pour chaque cas je doit calcule un critre d'optimisation (c'est une autre fonction ) et au final il faut que j arrive a avoir le num de la sequance les taches traiter et dans quelle machine sont traiter
            je crois ke c clair maintenant
            0
            1. Modérateur
              Est-ce que tu pourrais expliquer en français ce que tu veux faire, parce qu'avec ton code C, je ne vois pas du tout quel est ton but, ni de quelle façon tu utilises la première partie de ton problème
              0
              1. Error : pointer/array required
                main.c line 56 tabsquence[*g]->tabmachine[numachine]->tabordo[k]->numjob=numtache;

                Error : cannot convert
                'struct squence (*)[15]' to
                'int *'
                main.c line 115 Recherche( &tabsquence,&g);

                je recoit ces deux erreur mais je comrend pas ce que ca veut dire
                0
                1. Enregistrer(solution s, int M, int *g ) // ici un simple affichage, modifiable ‡ volontÈ
                  {

                  int numtache,numachine,k;
                  k=0;

                  printf("seq=%ld \n ",*g);
                  return (*g); --------------------------------> ici vers main
                  for (numachine=0; numachine<M; numachine++)
                  {
                  printf("Machine %ld : ",numachine );
                  for (numtache=0; numtache<nbtache; numtache++)
                  if (s[numachine][numtache]==true){
                  printf("%ld ",numtache);

                  return (numtache); --------> comme ici vers main
                  }
                  printf("\n");
                  return (numachine); -----------> comme ici vers main
                  }
                  *g=*g+1;
                  printf("\n" );
                  }

                  main()
                  {

                  int g=0;

                  Recherche( &g);
                  sequene =*g;
                  urne =num urne ;
                  balle =num boule ;
                  ////pour povoir construir a fur et a mesure mes sequences avec les urnes et le num de belle dedans ,
                  si je peut le faire aussi dans la fonction enregitrer aussi c era bien bien mais dans ce derner cas je sais pas comme faire pour declaer une structure dans une fonction
                  system("PAUSE");

                  }
                  0
                  1. re slt KX tu pourrai pas me donner une idee comme pouvoir renvoyer les valeur de num boule et num urne et le numero de cas a MAIN pour les traiter (evidament a fur et a mesure ),pour les traiter chaquen a part
                    merci d avance
                    0
                    1. Modérateur
                      Peux-tu donner un exemple de ce que tu veux faire ?
                      0
                  2. la je suis sur la 2 eme partie de mon probleme qui consite a a considérer que chaque cas genere je doit sauvgarder chaque cas avec les num boul et la num urne ou elle se trouve
                    exemple de ma structure
                    tabcas[*g].taburne[numurne].tabboule [k].numboul
                    c-a-d
                    pour 3urne et 3 boulle
                    le cas 1 avec l’urne 1 dedans les boule 1 ,boule 2 ,boule 3
                    le cas 2 avec urne 1 dedans la boule 1 ,boule 3
                    le cas 2 avec urne 2 dedans la boule 3
                    …..
                    .
                    .
                    .
                    .
                    . ect ….
                    c''est une structure ou chaque cas a ces urnes ou chaque urne a ces plalace pour placer les boules
                    0
                    1. Modérateur
                      Ne serait-il pas plus simple de repartir de mon type solution ?
                      typedef bool solution[nbUrne][nbBoule];

                      Ensuite si tu veux l'enregistrer tu ouvres un fichier binaire, et à chaque fois qu'un cas arrive dans la procédure enregistrer tu l'enregistre dans le fichier... À la fin du programme tu fermes le fichier et c'est fini !

                      En plus le type bool ne prend qu'un bit (du moins en C++, en C il n'existe pas donc j'en sais rien)
                      Ça veut dire que par exemple pour N=5, tu as 5*5=25 bits par cas
                      Et donc avec 52 cas ça te donne 1300 bits=163 octets !!!

                      L'avantage de mon type solution c'est que chaque cas a la même taille, la façon dont tu veux le faire paraît plus dur et moins efficace...
                      0
                  3. slt
                    merci pour les infos
                    je crois je vait rest encore sur le C .
                    une question :
                    Est t'il possible en C d' introduire une structure dans une fonction ???
                    0
                    1. Modérateur
                      Que veux tu dire par là ?

                      Une structure définit un nouveau type, tu peux utiliser les éléments de ce nouveau type n'importe où dans ton programme y compris dans une fonction !

                      Si c'est pas ça explique un peu plus ce que tu voudrais faire...
                      0
                  4. Ok pas de soucis.
                    C'étais juste une question à la base.
                    Et puis le programme est fini de toute façon.
                    0
                    1. Modérateur
                      Alors juste pour répondre à ta question, oui on peux mettre du Prolog en C !

                      Après une recherche rapide il semble que l'on puisse utiliser ce genre de code :
                           #include <sicstus/sicstus.h>
                           
                           SP_pred_ref
                           SP_predicate(char *name_string,
                           	     long arity,
                           	     char *module_string);
                      À condition bien sûr de posséder la librairie SICStus

                      Il y a surement d'autres méthodes qui le permettent (voir aussi SWI-Prolog C++)
                      0
                  5. Prolog est un langage de programmation logique donc n'est pas un langage impératif ( comme la plupart de ceux qu'on utilise couramment java,C,c#, vb, cobol, etc....).

                    En gros, les langage impératifs sont des programmes ou des ordres sont données (des instructions).

                    Or en prolog (et dans les autres langages de programmation logique), on établies des prédicats et le but d'un programme est donc de satisfaire au prédicats (l'ordinateur te balance toutes les variables possibles (dans un ordre quand même) jusqu'au moment ou il établit que le prédicat principal est satisfait (="méthode" principale) ou irréalisable (après avoir énuméré tout les solutions qu'il a testé donc toutes les combinaisons de variables possibles)).

                    Donc en gros le principe est de justement de ne jamais trouvé de solution (il te balancera tout les valeurs possible mais en te disant qu'il a rien trouvé) et d' écrire chaque combinaison qu'il trouve.

                    Alors pour le rendre compatible sur c je sais que c'est faisable mais pas comment (car g vu un cours d' université à liege (je pense)où ils intègrent du prolog dans du code c).
                    J'essaierais de trouver le moyen.
                    0
                    1. Modérateur
                      Insérer du Prolog en C n'a aucun intérêt si on est pas capable de faire du Prolog alors qu'on est capable de faire du C...
                      D'autant que le C s'est tout de suite imposé dans la résolution du problème puisque c'est le langage qu'utilise Coco !
                      0
                  6. slt ,je connais pas ce language tu pourrai pas me dire un peu plus ,peut etre il est intressent .
                    j ai vue sur google mais je comprend pas comme le rendre compatible avec le C
                    0
                    1. Na tu pas penser a insérer du prolog dans ton code c?
                      0
                      1. 1001 merci pour votre aide ,et tt vous effort ca ma bien aidé
                        l'algorithme fonction tres bien ,
                        0
                        1. ton type Bool ne correspond pas vraiment au boolean, il faut modifier dans Enregistrer:
                          if (s[numUrne][numBoule]==true) printf("%ld ",numBoule+1);
                          1
                          1. Modérateur
                            Le plus simple aurait en fait été de faire :
                            typedef int bool;
                            const bool true=1;
                            const bool false=0;
                            L'erreur est dû au fait que j'utilise du C++ et toi du C...
                            0
                        2. juste pour expliquer apres excution on voit afficher les truc a gauche alors que il faut les trucs a droit

                          Urne1: 2 3 ---------------------------------->Urne 1: 1
                          Urne2 : 1 3 -----------------------------------> Urne 2: 2
                          Urne3: 1 2 ------------------------------------>Urne 3: 3
                          0
                          1. slt
                            comme le programme ne voulait pas s 'executer sur le dev a cause de type booleen j ai changer ca declaration

                            #include <stdio.h>
                            #include <stdlib.h>

                            const int nMax=3;//Remarque nMax doit être > 1
                            const int nbUrne=3;
                            const int nbBoule=3;
                            typedef enum {true,false} Bool; ----------------> ici

                            typedef Bool solution[3][3];

                            est voila le resultat je VOIS AFFICHER

                            Urne 1: en principe ici il va avoir 1 2 3

                            Urne1: 3
                            Urne2 : 1 2

                            Urne1: 2
                            Urne 2: 1 3

                            Urne1: 2 3
                            Urne 2: 1

                            Urne1: 2 3 Urne 1: 1
                            Urne2 : 1 3 ici Urne 2: 2
                            Urne3: 1 2 Urne 3: 3

                            alors si je me trompe pas pour l afichage des autre cas ca depond de le boule enregistrer, ou c cas que je voit sont ceux uniquement calculer par l'algorithme .parce que j eesyer avec 4 cas ,je voit bien que la meme boule peut etre dans deux urne different exatement dans 7/15 cas ce que fait ke les vrai cas il ne reste que 7 (exemple dans l exemple precedent la boule 1 revient deux fois (23,13,12);
                            0
                            • 1
                            • 2
                            • 3