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 :

Bin packing : algorithme pour énumerer toutes les solutions


Sujet :

Algorithmes et structures de données

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 10
    Points : 11
    Points
    11
    Par défaut Bin packing : algorithme pour énumerer toutes les solutions
    Salut à tous, je doit implémenter en C une "solution optimale" pour le problème du bin packing j'ai fait des méthodes "classic" pour commencer genre le first fit et le best fit. mais pour l'optimisation j'aurai besoin d'énumérer toutes les solutions possible afin de prendre la meilleur.
    Esce que quelqu'un pourrais m'aider a trouver un algo (récursif) qui ferai ça???
    Merci d'avance

  2. #2
    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 : 51
    Localisation : France, Hérault (Languedoc Roussillon)

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

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Une exploration complète de l'arbre des solutions, ca va être énorme !

    Il faut trouver des critères pour arrêter l'exploration au plus tôt. Sinon ca va pas être gérable.
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 10
    Points : 11
    Points
    11
    Par défaut
    Oui c'est sur. mais au fait dans un premier temps j'aurai besoin d'enumerer les solutions sans utiliser un arbre... j'ai pensé à un tableau binaire mais je sais pas comment faire...
    http://dept-info.labri.fr/ENSEIGNEME...in-packing.pdf voila le lien vers le probleme; c'est surtout la methode exacte qui m'interesse...
    Merci pour ton aide

  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 : 51
    Localisation : France, Hérault (Languedoc Roussillon)

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

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Ton document explique qu'il faut faire une exploration de l'arbre.

    - Le premier élément est assigné arbitrairement au sac 1 : X[1]=1.

    - On explore alors les solutions possibles pour l'élement #2 :
    --> dans le sac #1
    --> dans un nouveau sac #2
    pour chacune de ces 2 possibilités, on explore les solutions possibles pour l'élement #3

    Ca peut se faire facilement par recursion:

    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
     
    DEBUT explorer(#i)
     
    	Pour chaque sac #s
    		si l'element #i rentre dans le sac #s alors
    			affecter #i à #s
    			explorer(#i+1)
    			retirer #i de #s
    		fin si
    	Fin Pour
     
    	Créer un nouveau sac #s
    	affecter #i à #s
    	explorer(#i+1)
    	retirer #i de #s
    	Supprimer le nouveau sac #s
     
    FIN
    Il est recommandé de limiter la création de nouveaux sacs. Par exemple, si on a déjà trouvé une solution avec K sacs, c'est inutile de tester une solution avec K+1 sacs. Elle sera forcément moins bonne.
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 10
    Points : 11
    Points
    11
    Par défaut
    Oui je vois maintenant comment ça marche. Au niveau algorithmique je sais maintenant comment on peut faire, mais pour programmer tout ça je me demandez s'il avait un moyen pour que je n'utilise pas un arbre? parce que j'utilise trois structure donc je m'y perd un peu quand je dois manupuler un arbre ...

    voila mes structures:

    Code C : 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
    struct objet
    {
      char* nom;
      float poids;
    };
     
    struct sac
    {
      int nb_objet; /* =======> initialisé à 0... puis a chaque qu'on ajoute un objet on fais +1 */
      float poids_courant;
      objet *listeObjet; /* ==>>c'est genre un "tableau" d'objet dans lequel je peux avancer pour avoir les infos sur les objet qui sont dans le sac...*/
    };
     
    struct containeurSac 
    {
      sac * listeDeSac; /*==>il permet d'acceder aux sac du container et de "voir" leur contenu */
     
      int nombre_sac; /* ==> initialisé à 0 et nous donne le nombre de sac utilisé... */
    };

    Encore merci pour ton aide

  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 : 51
    Localisation : France, Hérault (Languedoc Roussillon)

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

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par cochemar_bin_packing Voir le message
    Oui je vois maintenant comment ça marche. Au niveau algorithmique je sais maintenant comment on peut faire, mais pour programmer tout ça je me demandez s'il avait un moyen pour que je n'utilise pas un arbre? parce que j'utilise trois structure donc je m'y perd un peu quand je dois manupuler un arbre ...
    L'arbre ca représente l'espace des solutions a explorer : on doit faire des choix qui nous conduisent à d'autre choix, etc. Bref ca forme un arbre de solutions.

    Dans le code, on ne manipule pas un arbre au sens "structure de données" (noeud, feuille). On ne fait qu'explorer l'arbre. On n'a donc besoin que d'une pile qui contient les choix (= les noeuds) qu'on a choisi d'explorer. Cette pile nous permet de revenir en arrière dans nos choix, et d'en faire d'autres.

    Le plus simple c'est de faire un algo recursif car, dans ce cas, la pile est gérée automatiquement par le langage (appels de fonctions).
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 10
    Points : 11
    Points
    11
    Par défaut
    Ben j'ai essayé d'ecrire une fonction recursive mais elle marche pas, pourtant j'ai fait que traduire l'algo que tu m'as donné ben afin je crois

    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
     
    bool egalite_objet(objet o1, objet o2)
    {
      int cmp_nom = strcmp(o1->nom,o2->nom);
      return o1->poids == o2->poids && cmp_nom == 0; 
    }
     
     
     
    static int chercher_indice(sac s, objet o)
    {
      for(int i = 0; i<s->nb_objet; i++)
        if(egalite_objet(s->listeObjet[i],o))
          return i;
      return -1;
    }
     
    void enlever_objet(sac s, objet o)
    {
      s->poids_courant -= o->poids;
      s->nb_objet -= 1;
      int i = chercher_indice(s,o);
      (s->listeObjet[i]) = NULL;
    }
     
    void enlever_sac(containeurSac c, sac s)
    {
      c->nombre_sac -= 1;
      (c->listeDeSac[c->nombre_sac-1]) = NULL;
    }
     
     
     
    void recursif(objet tab_objet[], containeurSac c, int i, int nb_sac_max, float POIDS_LIMITE)
    {
      for(int j =0; j < c->nombre_sac; j++)
        {   
          if(ajout_possible_dans_sac(c->listeDeSac[j],tab_objet[i],POIDS_LIMITE))
    	{
    	  ajouter_objet_dans_sac(c->listeDeSac[j], tab_objet[i]);
    	  recursif(tab_objet, c, i+1, nb_sac_max, POIDS_LIMITE);
    	  enlever_objet(c->listeDeSac[j], tab_objet[i]);
    	}
        }
      if(c->nombre_sac < nb_sac_max)
        {
          ajouter_sac_containeurSac(c);
          recursif(tab_objet, c, i+1, nb_sac_max, POIDS_LIMITE);
          enlever_objet(c->listeDeSac[i], tab_objet[i]);
          enlever_sac(c, c->listeDeSac[c->nombre_sac-1]);
        }
    }

  8. #8
    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 : 51
    Localisation : France, Hérault (Languedoc Roussillon)

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

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    1ere remarque : il faut penser a "sortir" de l'appel recursif. A force d'explorer l'élément suivant, tu vas finir par arriver au bout de la liste des éléments.

    2nde remarque : ca me parait bien compliqué de travailler avec des listes chainées. Ton document PDF suggère de passer par un tableau qui contient les affectations #element/#sac. Ca me parait plus simple.


    Exemple d'implémentation:
    Code java : 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
     
    int N=7; // Nb d'elements
    int[] P={3, 4, 4, 3, 3, 2, 1}; // poids des éléments
    int Pmax=10; // le poids max d'un Sac
     
    int SacLimit = N; // limite du nombre de sacs (au pire : un par element)
    int SacMax = 0; // Nb de sacs utilisés
    int[] S = new int[SacLimit]; // poids de chaque sac
     
    int[] X = new int[N]; // les affectations element/sac
     
    void resoudre() {
    	// force l'affectation du 1er element au 1er sac
    	creerNouveauSac();
    	affecter(0,0);
     
    	// exploration recursive
    	explore(1);
    }
     
    void explore(int i) {
    	if (i>=N) { // sortie de la recursion
    		if (SacMax<SacLimit) { // nouvelle solution, meilleure que la precedente
    			SacLimit=SacMax;
    			System.out.println(Arrays.toString(X));
    		}
    		return;
    	}
     
    	// met l'element dans chaque sac, et explore l'element suivant 
    	for(int s=0;s<SacMax;s++) {
    		affecter(i,s);
    		if (S[s]<=Pmax) explore(i+1);
    		retirer(i,s);
    	}
     
    	// met l'element dans un nouveau sac
    	creerNouveauSac();
    	if (SacMax<SacLimit) {
    		affecter(i,SacMax-1);
    		explore(i+1);
    		retirer(i,SacMax-1);
    	}
    	SupprimerNouveauSac();
    }
     
    // fonctions utilitaires
    void creerNouveauSac() { SacMax++; S[SacMax-1]=0; }
    void SupprimerNouveauSac() { SacMax--; }
    void affecter(int i, int s) { X[i]=s;  S[s]+=P[i]; }
    void retirer(int i, int s)  { X[i]=-1; S[s]-=P[i]; }
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 10
    Points : 11
    Points
    11
    Par défaut
    Salut j'ai adapté ton code à ma structure mais j'ai pas eu le temps de le tester.

    Au fait je n'ai pas compris cette partie du code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if (SacMax<SacLimit) { // nouvelle solution, meilleure que la precedente
    	SacLimit=SacMax;
    c'est quoi le SacLimit et le sacMax ???je m'y perd un peu au fait.
    Parce que si SacMax est initialisé a 0. le "if" sera toujours vrai et je vois mal comment on pourrait mettre SacLimit à 0 (SacLimit=SacMax.
    Je crois qu'il y a quelque chose qui va pas...

  10. #10
    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 : 51
    Localisation : France, Hérault (Languedoc Roussillon)

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

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par cochemar_bin_packing Voir le message
    c'est quoi le SacLimit et le sacMax ???je m'y perd un peu au fait.
    Parce que si SacMax est initialisé a 0. le "if" sera toujours vrai et je vois mal comment on pourrait mettre SacLimit à 0 (SacLimit=SacMax.
    Je crois qu'il y a quelque chose qui va pas...

    SacMax c'est le nombre de sac utilisé actuellement (= lors de l'exploration de "cette" solution).

    Comme notre algorithme a la possibilité de "creer" des nouveaux sacs, il faut lui fixer une limite, sinon il va explorer des solutions avec 5548721 sacs pour voir si elles sont valides . SacLimit représente le nombre "maximum" de sac que l'algorithme est autorisé a créer. Au départ, il faut bien sur que ce nombre soit assez grand pour trouver au moins une solution. J'ai choisi de prendre SacLimit=N, car je suis sur que c'est une solution au problème (1 sac pour chaque element).

    Le "if (SacMax<SacLimit)" n'est testé que dans le cas "if (i>=N) " . C'est à dire uniquement lorsqu'on a terminé la recursion, et donc trouvé une solution valide. Auquel cas, on regarde si cette "nouvelle" solution utilise moins de sac que la limite actuelle. Si c'est le cas, alors cette "nouvelle" solution est meilleure que la limite... et donc elle devient la nouvelle limite.
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  11. #11
    Membre éclairé
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Points : 842
    Points
    842
    Par défaut
    Comme déjà dit, je pense que la solution la plus simple, et la moins coûteuse en mémoire (pour pas dire la plus rapide), est la programmation dynamique !
    Revois le lien que je t'ai donné, la solution est dedans (à quelques modifications près).
    Plus tu pédales moins fort, moins t'avances plus vite.

  12. #12
    Nouveau Candidat au Club
    Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2012
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    bonjour a tous,je travaille sur un problème de découpe ( bin packing 2D)
    le problème s'énonce comme suit!
    on dispose de plaques mères de 48x96 dm
    on doit découper à partir des plaques mères: 8 plaques de 36x50 dm
    13 plaques de 24x36 dm
    5 plaques de 20x60 dm
    15 plaques de 18x30 dm

    les découpes doivent etre satisfaites tout en minimisant le nombre de plaques mères utilisées ainsi que la chute de matière.
    j'aimerai savoir comment faire pour énumérer les différents plans de coupe possibles pour modéliser ce problème sous forme de programme linéaire en nombres entiers.
    merci d'avance pour votre aide!

Discussions similaires

  1. SAS® 9.4 arrive : du Cloud pour toutes les solutions SAS
    Par actusas dans le forum Forum général SAS
    Réponses: 0
    Dernier message: 15/05/2013, 10h50
  2. Bin Packing Algorithme pour enumerer toutes les solutions
    Par cochemar_bin_packing dans le forum C
    Réponses: 5
    Dernier message: 22/04/2013, 03h12
  3. Réponses: 4
    Dernier message: 07/07/2006, 12h41
  4. [checkbox] Code pour cocher toutes les cases
    Par snakejl dans le forum Général JavaScript
    Réponses: 24
    Dernier message: 02/06/2006, 09h36
  5. Réponses: 8
    Dernier message: 17/10/2002, 12h52

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