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 :

Probl�me du sac � dos (Knapsack)


Sujet :

C++

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Homme Profil pro
    �tudiant
    Inscrit en
    Avril 2018
    Messages
    3
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Avril 2018
    Messages : 3
    Par d�faut Probl�me du sac � dos (Knapsack)
    Bonjour,
    je travaille sur le probl�me du sac � dos (knapsack). Je suis actuellement sur une premi�re �bauche de mon heuristique glouton, j'arrive � le compiler, cependant il ne renvoie pas les r�sultats attendus, et impossible d'afficher (cout) mes vecteurs pour voir o� �a bloque

    Voici mon code:
    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
    #include<iostream>
    #include<fstream>
    #include<string>
    #include<vector>
     
    using namespace std;
     
    struct Objet{
      int i;
      int wi;
      int pi;
    };
     
    struct Instance{
      int capacite;
      Objet vec;
    };
     
    struct Solution{
      int ps;
    };
     
    Instance lecture(){
      int taille;
      string filename;
      Instance I;
     
      cout << "Entrez le nom du fichier :" << endl;
      cin >> filename;
      ifstream inf(filename.c_str());
      inf >> taille >> I.capacite >> ws;
      vector<Objet> vec(taille);
     
      for (int i = 0; i < taille; i++){
        inf >> vec[i].wi >> vec[i].pi >> ws;
        vec[i].i=i;
      }
      inf.close();
     
     
     
      return I;
     
    }
    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
    #include<iostream>
    #include<fstream>
    #include<string>
    #include<vector>
    #include"knapsack.h"
    using namespace std;
     
    void echanger(int a, int b) {
      int tmp = a;
      a = b;
      b = tmp;
    }
     
    vector<double> tri(vector<double> u){
      int inversion=0;
      do{
       for(int i=0; i<u.size(); ++i){
        if(u[i]<u[i+1]){
          echanger(u[i], u[i+1]);
          inversion=1;
        }
      }
      } while(inversion);
      return u;
    }
    int main(){
      Instance I;
      Solution S;
      vector<double> u;
      vector<Objet> vec;
      lecture();
      for(int i=0; i<u.size(); ++i) u[i]=vec[i].pi/vec[i].wi ;
      tri(u);
      for(int i=0;i<u.size();++i) cout << vec[i].pi ;
      int i=0;
      while ( i < I.capacite){
        if (I.capacite-u[i]>=0){
          S.ps=S.ps+u[i];
          ++i;
        } else ++i;
      }
      cout << S.ps << endl;
      //for(int i=0;i<u.size();++i) cout << u[i] << endl;
      return 0;
    }
    Et voici le r�sultat :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    Entrez le nom du fichier :
    Data/ks_4_0
    0
    Merci de votre compr�hension et du temps que vous m'accordez.
    Cordialement.

  2. #2
    Membre Expert
    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    Juin 2011
    Messages
    760
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, H�rault (Languedoc Roussillon)

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 760
    Par d�faut
    Tu devrais s�rieusement envisager de monter le niveau de warning. Il y a au moins une variable non initialis�e (I.capacite) et un overflow (for(int i=0; i<u.size(); ++i) ...u[i+1]...).

    Mais le code contient beaucoup de probl�mes et de points d'am�liorations. En vrac:

    - using namespace std; est tr�s fortement d�conseill� dans un en-t�te, car son usage peut engendrer des conflits de nom.
    - Depuis c++11, std::ifstream peut prendre un std::string comme type de fichier.
    - Fermer le fichier � la fin de la fonction est inutile car le destructeur de std::ifstream le fait d�j�.
    - La fonction lecture devrait prendre un nom de fichier plut�t que de faire appel � std::cin.
    - echanger n'est qu'un std::swap qui ne peut pas fonctionner. Il faut lire un cours sur les r�f�rences.
    - Idem pour tri qui est � remplacer par std::sort. En plus, inversion ne repasse jamais � 0 ce qui provoque une boucle infinie.
    - Les valeurs bool�ennes se repr�sentent avec bool et non pas un int.
    - std::vector::size() retourne un std::vector::size_type, usuellement un std::size_t. Pas un nombre sign� comme int.
    - Les variables devraient �tre initialis�es au moment de leur d�claration et construite au plus tard.
    - C++ apporte les boucles sur intervalle: for (double x: u) std::cout << x;. Je suis persuad� que faire une boucle avec u.size().

  3. #3
    Candidat au Club
    Homme Profil pro
    �tudiant
    Inscrit en
    Avril 2018
    Messages
    3
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Avril 2018
    Messages : 3
    Par d�faut
    Tout d�abord merci de votre r�ponse riche en enseignements.
    Je tiens juste � pr�ciser que le c++ est tout nouveau pour moi, c�est pourquoi je vous conc�de volontiers mon manque de rigueur.
    J�ai cependant suivi votre conseil et augment� mon niveau de warning.

    Point par point :

    -Il me semblait bien que �I.capacite� �tait initialis� � �Instance I� ? Quant � l�overflow j�ai cru r�soudre le probl�me cependant j�obtiens une segmentation fault 11 � l�ex�cution du programme, est-ce li� ?
    -J�utilise using namespace stp afin de rester dans le cadre du cours qui m�est fourni par la fac qui, je pense, n�est pas � jour sur tout. Bien qu�effectivement c++ 11 ait 7ans.
    -L� encore j�ai rigoureusement suivi les exemples d�utilisation de ifstream de mon cours.
    -idem
    -Le passage par cin r�pond � une condition du sujet qui m�est propos�.
    -j�ai donc bien remplac� par swap, quant aux r�f�rences, je ne saisi pas � quelle moment celles-ci doivent intervenir.
    -malgr� un include<algorithm> sort ne fonctionne pas, j�ai donc corrig� ma fonction inversion.

    Je m�affaire � prendre en compte vos trois derniers point d�am�liorations bien que l� encore pour les boucles for je m�efforce de respecter au plus pr�s mon cours qui, tr�s rudimentaire, n�aborde pas la notion de boucles sur intervalle.

    Je vous fais parvenir la derni�re version de mon code ainsi que le r�sultat de son ex�cution.

    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
    #include<iostream>
    #include<fstream>
    #include<string>
    #include<vector>
     
    using namespace std;
     
    struct Objet{
      int i;
      int wi;
      int pi;
    };
     
    struct Instance{
      int capacite;
      Objet vec;
    };
     
    struct Solution{
      int ps;
      //vec is;
    };
     
    Instance lecture(int taille, string filename, Instance I){
      cout << "Entrez le nom du fichier :" << endl;
      cin >> filename;
      ifstream inf(filename.c_str());
      inf >> taille >> I.capacite >> ws;
      vector<Objet> vec(taille);
     
      for (int i = 0; i < taille; i++){
        inf >> vec[i].wi >> vec[i].pi >> ws;
        vec[i].i=i;
      }
      inf.close();
     
      return I;
     
    }
    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
    #include<iostream>
    #include<fstream>
    #include<string>
    #include<vector>
    #include"knapsack.h"
    using namespace std;
     
    /*void echanger(int a, int b) {
      int tmp = a;
      a = b;
      b = tmp;
      }*/
     
    vector<double> tri(vector<double> u, int taille){
      bool inversion;
      do{
        for(int i=0; i<taille+1; ++i){
        if(u[i]<u[i+1]){
          swap(u[i], u[i+1]);
          inversion=1;
        }else inversion=0;
      }
      } while(inversion);
      return u;
      }
    int main(){  
      int taille;
      string filename;
      Instance I;
      Solution S;
      vector<double> u;
      vector<Objet> vec;
      lecture(taille, filename, I);
      for(int i=0; i<taille; ++i) u[i]=vec[i].pi/vec[i].wi ;
      tri(u,taille);
      //for(int i=0;i<taille;++i) cout << vec[i].pi ;
      int i=0;
      while ( i < I.capacite){
        if (I.capacite-u[i]>=0){
          S.ps=S.ps+u[i];
          ++i;
        } else ++i;
      }
      cout << S.ps << endl;
      //for(int i=0;i<taille;++i) cout << u[i] << endl;
      return 0;
    }
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    MacBook-Pro-de-user:DM user$ ./heuristicexe
    Entrez le nom du fichier :
    Data/ks_4_0
    Segmentation fault: 11

  4. #4
    Expert confirm�
    Homme Profil pro
    Ing�nieur d�veloppement mat�riel �lectronique
    Inscrit en
    D�cembre 2015
    Messages
    1 599
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 62
    Localisation : France, Bouches du Rh�ne (Provence Alpes C�te d'Azur)

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement mat�riel �lectronique
    Secteur : High Tech - �lectronique et micro-�lectronique

    Informations forums :
    Inscription : D�cembre 2015
    Messages : 1 599
    Par d�faut
    Citation Envoy� par cnhkp Voir le message
    Il me semblait bien que �I.capacite� �tait initialis� � �Instance I� ?
    C'est pas totalement faux. Le param�tre Instance I cr�� une Instance initialis�e comme une copie du ce qui est re�u mais l'Instance transmise n'a aucun de ses champs initialis�s car provient de Instance I; du main().
    Citation Envoy� par cnhkp Voir le message
    Quant � l�overflow j�ai cru r�soudre le probl�me cependant j�obtiens une segmentation fault 11 � l�ex�cution du programme, est-ce li� ?
    La boucle allait 1 indice trop loin, elle va maintenant 2 indices trop loin!
    Citation Envoy� par cnhkp Voir le message
    J�utilise using namespace stp afin de rester dans le cadre du cours qui m�est fourni par la fac qui, je pense, n�est pas � jour sur tout. Bien qu�effectivement c++ 11 ait 7ans.
    En fait, �a a �t� cr�� pour le portage de code d'avant 1998, donc l'utiliser ici c'est avoir 20 ans de retard!
    Citation Envoy� par cnhkp Voir le message
    j�ai donc bien remplac� par swap, quant aux r�f�rences, je ne saisi pas � quelle moment celles-ci doivent intervenir.
    Elles sont apparues avant 1989, et sont une des premi�res choses � conna�tre pour la passage des param�tres des fonctions avec la bonne utilisation du mot const. �a n'est pas un "d�tail", si tes profs l'ont loup�, il faudra r�tablir la peine de mort, c'est gravissime.

    Sinon, ta classe Instance est curieuse. Elle contient une capacit� mais ne peut que stocker qu'un unique Objet, et tu sembles vouloir recr�er le concept de std::vector<>!
    - Fonction lecture(), tu remplis un tableau local vec qui dispara�t (comme toute variable locale) � la sortie de la fonction. Tu souhaitais peut �tre le mettre sans I.vec qui devrait �tre un tableau.
    - Fonctiontri(), elle ne fonctionne pas. En plus du parcours qui va 2 indices trop loin, la variable inversion est trop souvent mise � 0.
    ...

  5. #5
    Mod�rateur

    Avatar de Bktero
    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par d�faut
    Citation Envoy� par cnhkp Voir le message
    -j�ai donc bien remplac� par swap, quant aux r�f�rences, je ne saisi pas � quelle moment celles-ci doivent intervenir.
    Citation Envoy� par dalfab Voir le message
    Elles sont apparues avant 1989, et sont une des premi�res choses � conna�tre pour la passage des param�tres des fonctions avec la bonne utilisation du mot const. �a n'est pas un "d�tail", si tes profs l'ont loup�, il faudra r�tablir la peine de mort, c'est gravissime.
    Avant d'acheter planches et poutres pour construire une guillotine, tu peux d�j� lire la FAQ https://cpp.developpez.com/faq/cpp/?page=Les-references et https://cpp.developpez.com/faq/cpp/?...-a-ma-fonction

  6. #6
    Candidat au Club
    Homme Profil pro
    �tudiant
    Inscrit en
    Avril 2018
    Messages
    3
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Avril 2018
    Messages : 3
    Par d�faut
    Merci � vous deux pour ces r�ponses.
    Celles-ci s'av�rent effectivement enrichissantes pour moi puisqu'elles m'ouvrent pleins d'axes de recherche et de progression int�ressants.
    Cependant je suis limit� dans le temps et j'ai besoin de r�ponses plus concr�tes sur ma fonction main, en effet j'ai pu tester ma fonction lecture ind�pendemment et celle-ci donne des r�sultats qui me sont acceptables, bien que malgr� les consignes je n'ai pas (encore) utilis� de r�f�rences.
    En effet, je ne comprends toujours pas concr�tement o� je dois m'en servir.
    De plus savez vous pourquoi mes deux affichages cout ne retourne rien ? J'ai pu corrig� l'erreur de segmentation mais la fonction me renvoie toujours un 0 et rien d'autre.

Discussions similaires

  1. R�ponses: 2
    Dernier message: 24/02/2010, 23h08
  2. Compr�hension d'un algorithme sur le probl�me du sac � dos
    Par Treuze dans le forum Algorithmes et structures de donn�es
    R�ponses: 3
    Dernier message: 18/12/2006, 15h26

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