DrFred
DrFred

Reputation: 471

Bad Sorting a vector objects C++

I have a strange problem when I try to sort vector of custom object. I have this code:

class Chromosome {
public:
   Chromosome(int c_w);       
   void setFitness(double fit);
   double getFitness() const;                
};

and compare function:

bool compareChromosomes(const Chromosome* l, const Chromosome* r) {
   return l->getFitness() <= r->getFitness();
}

I create the vector of chromosome: vector<Chromosome*> popv; and I add some chromosomes.

when I try to sort the vector with sort(popv.begin(), popv.end(), compareChromosomes);

this is the result:

BEFORE SORT:

cromosoma 0: 0.205595

cromosoma 1: 0.370121

cromosoma 2: 0.363655

cromosoma 3: 0.363655

cromosoma 4: 0.858721

cromosoma 5: 0.192359

cromosoma 6: 0.582279

cromosoma 7: 0.202899

cromosoma 8: 0.205105

cromosoma 9: 0.187058

AFTER SORT

cromosoma 0: -0.474942

cromosoma 1: 0.187058

cromosoma 2: 0.192359

cromosoma 3: 0.202899

cromosoma 4: 0.205105

cromosoma 5: 0.205595

cromosoma 6: 0.363655

cromosoma 7: 0.363655

cromosoma 8: 0.370121

cromosoma 9: 0.582279

where is the problem?

Upvotes: 1

Views: 96

Answers (2)

MadCrazy
MadCrazy

Reputation: 123

The reason why 0.858721 is changed to -0.474942 is not because of your comparison function. There must be some other reason on the code you had not posted. Try the code below: the output is ok.

#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;

class Chromosome {
public:
  Chromosome(int c_w) :mCw(c_w) { }
  void setFitness(double fit) { mFit = fit; }
  double getFitness() const { return mFit; }
  int getCW() const { return mCw; }
private:
  int mCw;
  double mFit;
};

bool compareChromosomes(const Chromosome* l, const Chromosome* r) {
   return l->getFitness() <= r->getFitness();
}

int main( int argc, char *argv[] ) {
  // init your data
  vector<Chromosome *> popv;
  popv.push_back( new Chromosome( 0 ) );
  popv[ popv.size() - 1 ]->setFitness( 0.205595 );
  popv.push_back( new Chromosome( 1 ) );
  popv[ popv.size() - 1 ]->setFitness( 0.370121 );
  popv.push_back( new Chromosome( 2 ) );
  popv[ popv.size() - 1 ]->setFitness( 0.363655 );
  popv.push_back( new Chromosome( 3 ) );
  popv[ popv.size() - 1 ]->setFitness( 0.363655 );
  popv.push_back( new Chromosome( 4 ) );
  popv[ popv.size() - 1 ]->setFitness( 0.858721 );
  popv.push_back( new Chromosome( 5 ) );
  popv[ popv.size() - 1 ]->setFitness( 0.192359 );
  popv.push_back( new Chromosome( 6 ) );
  popv[ popv.size() - 1 ]->setFitness( 0.582279 );
  popv.push_back( new Chromosome( 7 ) );
  popv[ popv.size() - 1 ]->setFitness( 0.202899 );
  popv.push_back( new Chromosome( 8 ) );
  popv[ popv.size() - 1 ]->setFitness( 0.205105 );
  popv.push_back( new Chromosome( 9 ) );
  popv[ popv.size() - 1 ]->setFitness( 0.187058 );
  // sort
  sort( popv.begin(), popv.end(), compareChromosomes );
  for( size_t i = 0; i < popv.size(); i++ ) {
    cout << "cromosoma " << popv[i]->getCW() << ":" << popv[i]->getFitness() << endl;
  }

  return 0;
}

Upvotes: 1

Luchian Grigore
Luchian Grigore

Reputation: 258568

Your compare function is not strict - for two equal chromosomes, it returns true for compareChromosomes (regardless of order). Replace your condition with strict less:

bool compareChromosomes(const Chromosome* l, const Chromosome* r) {
   return l->getFitness() < r->getFitness();
   //                     |
   //                  <, not <=
}

Upvotes: 4

Related Questions