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 :

Sort personalis� ou sort sur index.


Sujet :

C++

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre confirm�
    Inscrit en
    Juin 2003
    Messages
    223
    D�tails du profil
    Informations personnelles :
    �ge : 41

    Informations forums :
    Inscription : Juin 2003
    Messages : 223
    Par d�faut Sort personalis� ou sort sur index.
    Bonjour,


    Bon voila j'ai un probleme au niveau des sorts en C++, et je me pose plusieurs questions.

    Pour r�sumer l'id�e: J'ai une image, et une liste de petit patch 20x20 pixels a differentes positions sur cette images.

    chaque patch � :

    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
     
    class MptIIMPatch {
    private:
    	uint32 _x,_y; //Coordonées du patch sur l'image
    	int _nof_histo;
    	double _entropy; //Entropy de l'histogram du patch
    public:
    	uint32 *histo; //Tableaux representant un histogram a 16 niveaux
            uint32 mean,var; //moyenne et variance du patch sur l'image.
     
     
    	// Constructor Destructeur etc..
    ...
     
    };
    mon but etant donc de tester environ 500 patchs al�atoirements et de les trier selon leur entropy pour recuperer les 50 meilleurs.

    Alors comme je commence le c++ j'essaye d'utiliser au plus les library.

    Id�e 1:
    Remplir un vecteur avec chaque entropy, remplir un autre avec des index de 0 � 499, et faire un sort sur l'entropy et de swaper l'index simultan�ments. (Pour ceux qui utilise matlab je pense que vous avez d�j� test� cette fonction)

    Le but etant donc d'avoir un tableaux avec l'entropie ordonn�e mais aussi un autre avec l'ancien index de l'entropie avant le sort. ainsi je prend les 50 premiers index et retrouve les 50 meilleurs patchs.

    J'ai cherch� un peu dans la stl mais j'ai rien trouv� qui puisse faire ca.

    Id�e 2:
    utiliser le custom sort du FAQ. : http://c.developpez.com/faq/cpp/?pag...TL_custom_sort

    Malheureusement ca marche pas avec ma class

    Voila ce que j'ai fait (dans une classe contenant plusieurs object dont un vecteur de MptIIMPatch;

    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
     
    /* in MptLayIIM.hpp */
     
    #include <vector>
    #include <algorithm>
    #include "MptIIMPatch"
     
    class MptLayIIM {
    private:
            ...
    	std::vector<MptIIMPatch> _patchVec; 
    public:
    ...
    };
     
    /* in MptLayIIM.cpp */
     
    struct SortByEntropy
    { 
        bool operator ()(const MptIIMPatch & p1,const MptIIMPatch & p2 ) const 
        { 
            return p1.getEntropy() < p2.getEntropy(); 
        } 
    }; 
     
    void MptLayIIM::getGoodPatches(int nof_patch) {
    	//Check Vector size
    	if(_patchVec.size() != nof_selected) _patchVec.resize(nof_patch);
    	//Build new random coordinate value
    	this->setRandPatchesCoord(nof_patch);
    	//Get Patches Values for testing
    	this->getPatchesValues(nof_patch);
     
    	for(int i(0);i<N_PTEST;++i) {
    			_patchVec[i].setEntropy();
    		}
    		std::sort(_patchVec.begin(),_patchVec.end(), SortByEntropy()); 
     
    }
    Bon ma premiere erreur sont les const qui ne marche pas mais meme si je les enleves j'ai bcp d'erreur provenant de la stl

    Ex:/usr/lib/gcc/i486-linux-gnu/4.0.3/../../../../include/c++/4.0.3/bits/stl_algo.h: In function �const _Tp& std::__median(const _Tp&, const _Tp&, const _Tp&, _Compare) [with _Tp = MptIIMPatch, _Compare = SortByEntropy]�:

    De plus je me demandais comment fonctionnait ce sort,
    si il copiait les pointeurs sur les objets (ou leur references) sans copi� lchaques champs ou il fait une copie de chaque champs (dans ce cas que ce passe t'il avec uint32 histo[].


    PS: Je me souviens d'avoir utiliser une fois en C un sort qui n'est pas complet... c.a.d je sort les 50 premiers et le reste ca m'est �gal. si vous vous souvener du nom ca m'interesse.

    Merci d'avance !!!

  2. #2
    Expert confirm�
    Avatar de Luc Hermitte
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2003
    Messages
    5 296
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : A�ronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Ao�t 2003
    Messages : 5 296
    Par d�faut
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    std::vector<MptIIMPatch> _patchVec; 
    ....
    class MptIIMPatch {
    ...	uint32 *histo;
    j'esp�re que c'est une vue et non une donn�e dont MptIIMPatch est responsable. Tu vas avoir des ennuis sinon.

    Tu peux ensuite avoir un vecteur d'indices qui pointent vers _pathVec (NB: le pr�fixage par _ est globablement r�serv� aux impl�menteurs du standard), et trier ces indices selon un pr�dicat qui va comparer les _pathVec[] indic�s par les �l�ments tri�s.

    J'avais pas post� une solution qui faisait cela il y a bien longtemps? (*)
    Sinon, je crois que boost.multi_index sert dans cette th�matique.

    Si ton tri tu ne le veux pas complet, tu peux utiliser les autres fonctions de tri de <algorithm>. -> std::partial_sort. (et sa version stable).

    (*) Visiblement oui, vu que j'ai retrouv� le 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
    45
    46
    47
    48
    49
    50
    51
    52
    #include <vector>
    #include <algorithm>
    #include <iostream>
     
    struct paire : std::pair<int, int> {
        paire(int i) {
            static int j;
            first = i;
            second = j++;
        }
        friend bool operator<(const paire & p1, const paire & p2) {
            return p1.first < p2.first;
        }
     
        friend std::ostream & operator<<(std::ostream & os, const paire p) {
            return os << p.first << "  -- " << (1+p.second) << "e";
        }
    };
    typedef std::vector<paire> V;
     
    template <typename T>
    struct PrintToOs 
    {
        PrintToOs(std::ostream & os) : os_(os) {}
        std::ostream & operator() (const T* v) const {
            return os_ << *v << std::endl;
        }
        std::ostream & operator() (const T & v) const {
            return os_ << v << std::endl;
        }
    private:
        std::ostream & os_;
    };
     
    int main (int argc, char **argv)
    {
        int tab[] = { 34, 8, 6, 23 };
        V v(tab, tab+(sizeof(tab)/sizeof(tab[0])));
     
        std::sort(v.begin(),v.end());
        std::vector<int> r(sizeof(tab)/sizeof(tab[0]));
        int i=0;
        for (V::const_iterator it=v.begin(); it != v.end(); ++it) {
            r[it->second] = ++i;
        }
     
        std::for_each(v.begin(),v.end(), PrintToOs<paire>(std::cout));
        std::cout << "Résultat:\n";
        std::for_each(r.begin(),r.end(), PrintToOs<int>(std::cout));
     
        return 0;
    }
    C'est bizarre, il me semblait m'y �tre d�j� pris autrement et bien plus simplement, mais je ne retrouve pas. Mais bon, c'est tellement vite refait.
    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 <vector>
    #include <algorithm>
    #include <iostream>
     
    template <typename T> struct IndirectCmp
    {
        IndirectCmp(T const* first) : first_(first) {}
        bool operator()(int rhs, int lhs) const {
            return first_[rhs] < first_[lhs];
        }
    private:
        T const * first_;
    };
     
     
    int main ()
    {
        const int tab[] = { 34, 8, 6, 23, 12 };
        const int S = sizeof(tab)/sizeof(tab[0]);
        std::vector<int> indices(S);
     
        unsigned int nb;
        while (
                std::cout << "\nOn en tri combien (<="<<S<<")?\n-> "
                , std::cin >> nb)
        {
            if (nb > S) { continue; }
     
            for (int i=0; i!=S ; ++i) { indices[i] = i; }
     
            std::partial_sort(
                    indices.begin(),
                    indices.begin()+nb,
                    indices.end(),
                    IndirectCmp<int>(&tab[0]));
     
            for (int i=0; i!=S ; ++i) {
                const int idx = indices[i];
                std::cout << "t[" << idx << "]=" << tab[idx] << "\n";
            }
        }
     
        return EXIT_SUCCESS;
    }
    Je te laisse adapter. Il y a moyen de rendre IndirectCmp plus g�n�rique pour utiliser autre chose que "<" pour r�aliser la comparaison.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne r�ponds � aucune question technique par le biais de ce m�dia. Et de toutes fa�ons, ma BAL sur dvpz est pleine...

  3. #3
    Expert confirm�
    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    D�cembre 2003
    Messages
    3 549
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (�le de France)

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

    Informations forums :
    Inscription : D�cembre 2003
    Messages : 3 549
    Par d�faut
    Bon ma premiere erreur sont les const qui ne marche pas mais meme si je les enleves j'ai bcp d'erreur provenant de la stl
    Ta fonction membre getEntropy n'est probablement pas const.
    Apprends � �crire de mani�re const-correcte et plus aucun probl�me.

    Ex:/usr/lib/gcc/i486-linux-gnu/4.0.3/../../../../include/c++/4.0.3/bits/stl_algo.h: In function �const _Tp& std::__median(const _Tp&, const _Tp&, const _Tp&, _Compare) [with _Tp = MptIIMPatch, _Compare = SortByEntropy]�:
    Ceci n'est pas une erreur. �a indique simplement o� l'erreur s'est produite.
    Apprends � lire et � comprendre les messages d'erreurs.

    uint32 *histo; //Tableaux representant un histogram a 16 niveaux
    Fortement d�conseill�, � moins que tu cherches � optimiser l'utilisation m�moire de MptIIMPatch.

  4. #4
    Membre confirm�
    Inscrit en
    Juin 2003
    Messages
    223
    D�tails du profil
    Informations personnelles :
    �ge : 41

    Informations forums :
    Inscription : Juin 2003
    Messages : 223
    Par d�faut
    Hummmm je comprend pas quel est le probleme avec mon tableau d'histogram...?? Je ne suis pas sur voir comment je peux mieux faire?

    Je remet le code pour que vous compreniez la construction

    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
     
    /* In MptIIMPatch.hpp */
     
    class MptIIMPatch {
    private:
    	uint32 _x,_y; //Coordonées du patch sur l'image
    	int _nof_histo;
    	double _entropy; //Entropy de l'histogram du patch
    public:
    	uint32 *histo; //Tableaux representant un histogram a 16 niveaux
            uint32 mean,var; //moyenne et variance du patch sur l'image.
     
     
    	/**************************/
     
    	// Default Constructor	
    	MptIIMPatch();
    	// Constructor
    	MptIIMPatch(int nb_histo);
    	// Destructor
    	~MptIIMPatch(void);
     
    	/**************************/
     
    	void create(int nb_histo);
            inline double getEntropy() const;
    ...
    }
    inline double MptIIMPatch::getEntropy() const { return _entropy; }
     
    /* In MptIIMPatch.cpp*/
     
    #include "MptIIMPatch.hpp"
     
     
    MptIIMPatch::MptIIMPatch() 
    : _x(0), _y(0),mean(0), var(0), _nof_histo(0), _entropy(0), histo(0) {
    }
     
    MptIIMPatch::MptIIMPatch(int nb_histo) {
    	this->create(nb_histo);
    }
     
    MptIIMPatch::~MptIIMPatch() {
    	delete[] histo;
    }
     
    void MptIIMPatch::create(int nb_histo) {
    	_x=0;  _y=0; 
    	_nof_histo = nb_histo;
    	_entropy = 0.0;
    	mean=0; var=0;
    	histo = new uint32[_nof_histo];
    }
    ....
    Car je suis obliger de mettre un pointeurs pour pouvoir intialiser mon tableaux ainsi.
    Bien sur je pourrais utiliser un vector<uint32> histo, mais j'ai pas vraiment besoin de ca.

    EDIT: Bon je crois que j'ai quand meme un probleme dans ma version du custom sort ...
    ...
    Entering sortByEntropy
    Entering sortByEntropy
    *** glibc detected *** double free or corruption (fasttop): 0x080543a0 ***
    Abandon

    C'est a dire que je ne sais pas vraiment ou est l'erreur mais ca doit surement venir de mon probleme dans *hito

    Le mieux pour moi serait d'avoir un vecteur de pointeur sur les object patch, vector<MptIIMPatch *>
    Et de pouvoir reordon� ces pointeurs sans copi� les objets MptIIMPatch.

    Sinon ca serait la structure paire comme dans l'exemple.

    (NB: le pr�fixage par _ est globablement r�serv� aux impl�menteurs du standard),
    Moi j'ai lu que c'etait pour faire la distinction entre les variables private et public...
    Enfin bon ...




    Sinon pour le const, cela fait que je suis obliger d'appeler getEntropy() avec un objet constant, car j'ai fait un test avec mon _patchVec et ca marche sans avoir besoin de const.

  5. #5
    Membre confirm�
    Inscrit en
    Juin 2003
    Messages
    223
    D�tails du profil
    Informations personnelles :
    �ge : 41

    Informations forums :
    Inscription : Juin 2003
    Messages : 223
    Par d�faut
    Voila ma solution mais ca reste tres inspir� du C

    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
     
     
    struct SortByEntropyP {
        bool operator ()(const MptIIMPatch* p1,const MptIIMPatch* p2 ) const 
        {
            return p1->getEntropy() < p2->getEntropy(); 
        } 
    }; 
     
    void MptLayIIM::filtersPatches(int method) {
     
    	std::vector<MptIIMPatch *> pPatchVec(N_PTEST);
     
     
    	switch(method) {
    		// Technique #2 : Entropy (shanon) 
    		case ENTROPY_FILTER:
    		for(int i(0);i<N_PTEST;++i) {
    			_patchVec[i].setEntropy();
    			pPatchVec[i] = &_patchVec[i];
    		}
             	     std::partial_sort(pPatchVec.begin(),pPatchVec.begin+50,pPatchVec.end(), SortByEntropyP()); 
    		for(int i(0);i<70;++i)	pPatchVec[i]->print();
    	}
    }
    Comme ca ca marche parfaitement mais ca reste une solution tres orient� C, C'est dommage que j'ai ce probleme avec l'autre version ...

    Qqun peut m'expliquer comment ca marche ce sort (au niveau de la copy des elements) car j'aimerais bien eviter de programmer en C et faire plus orient� C++

  6. #6
    Expert confirm�
    Avatar de Luc Hermitte
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2003
    Messages
    5 296
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : A�ronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Ao�t 2003
    Messages : 5 296
    Par d�faut
    Ne saute pas d'�tapes. C'est normal que tu aies des probl�mes avec �a. Reprends la plus simple expression de ta mod�lisation.
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    struct T {
       T() : t_(new int[10]) {}
       ~T() { delete[] t_; }
    private:
       int * t_;
    };
    T ta1;
    T ta2(t1); // ka-boum
     
    T tb1;
    T tb3;
    tb3 = tb1; // re ka-boum + fuite de mémoire.
    Il y a ici un probl�me de dangling pointer (quelqu'un a une traduction intelligente?), car apr�s copie tu auras une double destruction de la m�me zone. Je vois que le message d'erreur de la glic est d'ailleurs on ne peut plus clair.
    NB: pour les newbs qui tombent l� dessus apr�s une recherche, ce bout de code est le plus pur exemple de mauvais code � bannir!

    Bref, quand tu veux une s�mantique de copie (ou plus g�n�ralement de valeur) pour tes objets, alors que ceux-ci sont responsables d'une (ou plusieurs) ressource(s), alors il faut blinder.

    Une des diverses raisons qui fait que l'on pr�f�re syst�matiquement utiliser des vecteurs qui sont copiables (au prix d'une duplication des �l�ments) -- une raison bien plus critique est la r�sistance aux exceptions qu'ils offrent.

    Je pense que tu auras divers �l�ments � assimiler dans la FAQ aux chapitres sur le RAII & cie -- je ne sais plus si elle traite des diverses fa�on de d�finir des copies, ou des les interdire.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne r�ponds � aucune question technique par le biais de ce m�dia. Et de toutes fa�ons, ma BAL sur dvpz est pleine...

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. Radix sort a du mal sur android ?
    Par Mikiya dans le forum Android
    R�ponses: 0
    Dernier message: 15/02/2011, 07h42
  2. [PHP-JS] Method Not Allowed sur index.html
    Par metatron dans le forum Langage
    R�ponses: 3
    Dernier message: 10/08/2006, 12h07
  3. R�ponses: 1
    Dernier message: 10/04/2006, 20h22
  4. [phpBB] Champ recherche sur index
    Par Dace dans le forum EDI, CMS, Outils, Scripts et API
    R�ponses: 2
    Dernier message: 01/11/2005, 18h51
  5. [pseudocode]Incompr�hesnion pour un tri sur index
    Par ImpaCt dans le forum Algorithmes et structures de donn�es
    R�ponses: 4
    Dernier message: 29/08/2005, 23h52

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