refactoring

This commit is contained in:
maartenkeijzer 2007-08-31 12:59:18 +00:00
commit b11638cd54
3 changed files with 0 additions and 340 deletions

View file

@ -1,120 +0,0 @@
#ifndef eoNSGA_II_Replacement_h
#define eoNSGA_II_Replacement_h
#include <moo/eoFrontSorter.h>
#include <eoReplacement.h>
/** @brief Fast Elitist Non-Dominant Sorting Genetic Algorithm
Adapted from Deb, Agrawal, Pratab and Meyarivan: A Fast Elitist
Non-Dominant Sorting Genetic Algorithm for MultiObjective
Optimization: NSGA-II KanGAL Report No. 200001
*/
template <class EOT>
class eoNSGA_II_Replacement : public eoReplacement<EOT>
{
public:
void operator()(eoPop<EOT>& parents, eoPop<EOT>& offspring) {
unsigned origSize = parents.size();
std::copy(offspring.begin(), offspring.end(), std::back_inserter(parents));
typename eoFrontSorter<EOT>::front_t front = sorter(parents);
for (unsigned i = 0; i < front.size(); ++i) {
assign_worths(front[i], front.size() - i, parents);
}
// sort on worth (assuming eoMOFitness)
std::sort(parents.begin(), parents.end());
// truncate
parents.resize(origSize);
}
eoFrontSorter<EOT> sorter;
private:
typedef std::pair<double, unsigned> double_index_pair;
class compare_nodes
{
public :
bool operator()(const double_index_pair& a, const double_index_pair& b) const
{
return a.first < b.first;
}
};
/// _cf points into the elements that consist of the current front
void assign_worths(const std::vector<detail::FitnessInfo>& front, unsigned rank, eoPop<EOT>& parents) {
typedef typename EOT::Fitness::fitness_traits traits;
unsigned i;
unsigned nObjectives = traits::nObjectives(); //_pop[_cf[0]].fitness().size();
std::vector<double> niche_distance(front.size());
for (unsigned o = 0; o < nObjectives; ++o)
{
std::vector<std::pair<double, unsigned> > performance(front.size());
for (i =0; i < front.size(); ++i)
{
performance[i].first = front[i].fitness[o];
performance[i].second = i;
}
std::sort(performance.begin(), performance.end(), compare_nodes()); // a lambda operator would've been nice here
std::vector<double> nc(front.size(), 0.0);
for (i = 1; i < front.size()-1; ++i)
{ // and yet another level of indirection
nc[performance[i].second] = performance[i+1].first - performance[i-1].first;
}
// set boundary at max_dist + 1 (so it will get chosen over all the others
//nc[performance[0].second] += 0;
nc[performance.back().second] += std::numeric_limits<double>::infinity(); // best on objective
for (i = 0; i < nc.size(); ++i)
{
niche_distance[i] += nc[i];
}
}
// now we've got niche_distances, scale them between (0, 1), making sure that infinities get maximum rank
double max = 0;
for (unsigned i = 0; i < niche_distance[i]; ++i) {
if (niche_distance[i] != std::numeric_limits<double>::infinity()) {
max = std::max(max, niche_distance[i]);
}
}
for (unsigned i = 0; i < front.size(); ++i) {
double dist = niche_distance[i];
if (dist == std::numeric_limits<double>::infinity()) {
dist = 1.0;
} else {
dist /= (1+max);
}
unsigned idx = front[i].index;
typename EOT::Fitness f = parents[idx].fitness();
f.setWorth(rank + dist);
//std::cout << "Base rank " << rank << " dist " << dist << " result " << (rank+dist) << std::endl;
parents[idx].fitness(f);
}
}
};
#endif

View file

@ -1,145 +0,0 @@
#ifndef eoNSGA_IIa_Replacement_h
#define eoNSGA_IIa_Replacement_h
#include <moo/eoFrontSorter.h>
#include <eoReplacement.h>
/** @brief Fast Elitist Non-Dominant Sorting Genetic Algorithm
Variant of the NSGA-II, where the ranking is based on a top-down distance based mechanism ( O(n^2)! )
*/
template <class EOT>
class eoNSGA_IIa_Replacement : public eoReplacement<EOT>
{
public:
void operator()(eoPop<EOT>& parents, eoPop<EOT>& offspring) {
unsigned origSize = parents.size();
std::copy(offspring.begin(), offspring.end(), std::back_inserter(parents));
typename eoFrontSorter<EOT>::front_t front = sorter(parents);
unsigned rank = parents.size();
for (unsigned i = 0; i < front.size(); ++i) {
rank = assign_worths(front[i], rank, parents);
}
// sort on worth (assuming eoMOFitness)
std::sort(parents.begin(), parents.end());
// truncate
parents.resize(origSize);
}
private:
eoFrontSorter<EOT> sorter;
double distance(const std::vector<double>& f1, const std::vector<double>& f2, const std::vector<double>& range) {
double dist = 0;
for (unsigned i = 0; i < f1.size(); ++i) {
double d = (f1[i] - f2[i])/range[i];
dist += d*d;
}
return dist;
}
unsigned assign_worths(const std::vector<detail::FitnessInfo>& front, unsigned rank, eoPop<EOT>& parents) {
unsigned nDim = front[0].fitness.size();
// find boundary points
std::vector<unsigned> processed(nDim);
for (unsigned i = 1; i < front.size(); ++i) {
for (unsigned dim = 0; dim < nDim; ++dim) {
if (front[i].fitness[dim] > front[processed[dim]].fitness[dim]) {
processed[dim] = i;
}
}
}
// assign fitness to processed
for (unsigned i = 0; i < processed.size(); ++i) {
typename EOT::Fitness f = parents[ front[ processed[i] ].index].fitness();
f.setWorth(rank);
parents[ front[ processed[i] ].index ].fitness(f);
}
rank--;
// calculate ranges
std::vector<double> mins(nDim, std::numeric_limits<double>::infinity());
for (unsigned dim = 0; dim < nDim; ++dim) {
for (unsigned i = 0; i < nDim; ++i) {
mins[dim] = std::min( mins[dim], front[ processed[i] ].fitness[dim] );
}
}
std::vector<double> range(nDim);
for (unsigned dim = 0; dim < nDim; ++dim) {
range[dim] = front[ processed[dim] ].fitness[dim] - mins[dim];
}
// calculate distances
std::vector<double> distances(front.size(), std::numeric_limits<double>::infinity());
unsigned selected = 0;
// select based on maximum distance to nearest processed point
for (unsigned i = 0; i < front.size(); ++i) {
for (unsigned k = 0; k < processed.size(); ++k) {
if (i==processed[k]) {
distances[i] = -1.0;
continue;
}
double d = distance( front[i].fitness, front[ processed[k] ].fitness, range );
if (d < distances[i]) {
distances[i] = d;
}
}
if (distances[i] > distances[selected]) {
selected = i;
}
}
while (processed.size() < front.size()) {
// set worth
typename EOT::Fitness f = parents[ front[selected].index ].fitness();
f.setWorth(rank--);
parents[ front[selected].index ].fitness(f);
distances[selected] = -1;
processed.push_back(selected);
selected = 0;
for (unsigned i = 0; i < front.size(); ++i) {
if (distances[i] < 0) continue;
double d = distance(front[i].fitness, front[processed.back()].fitness, range);
if (d < distances[i]) {
distances[i] = d;
}
if (distances[i] > distances[selected]) {
selected = i;
}
}
}
return rank;
}
};
#endif

View file

@ -1,75 +0,0 @@
#ifndef __EONDSorting_I_h
#define __EONDSorting_I_h
#include <moo/eoFrontSorter.h>
/**
The original Non Dominated Sorting algorithm from Srinivas and Deb
*/
template <class EOT>
class eoNSGA_I_Replacement : public eoReplacement<EOT>
{
public :
eoNSGA_I_Replacement(double _nicheSize) : nicheSize(_nicheSize) {}
void operator()(eoPop<EOT>& parents, eoPop<EOT>& offspring) {
unsigned origSize = parents.size();
std::copy(offspring.begin(), offspring.end(), std::back_inserter(parents));
typename eoFrontSorter<EOT>::front_t front = sorter(parents);
for (unsigned i = 0; i < front.size(); ++i) {
assign_worths(front[i], front.size() - i, parents);
}
// sort on worth (assuming eoMOFitness)
std::sort(parents.begin(), parents.end());
// truncate
parents.resize(origSize);
}
private:
void assign_worths(const std::vector<detail::FitnessInfo>& front, unsigned rank, eoPop<EOT>& parents) {
for (unsigned i = 0; i < front.size(); ++i)
{ // calculate whether the other points lie within the nice
double niche_count = 0;
for (unsigned j = 0; j < front.size(); ++j)
{
if (i == j)
continue;
double dist = 0.0;
for (unsigned k = 0; k < front[j].fitness.size(); ++k)
{
double d = front[i].fitness[k] - front[j].fitness[k];
dist += d*d;
}
if (dist < nicheSize)
{
niche_count += 1.0 - pow(dist / nicheSize,2.);
}
}
unsigned idx = front[i].index;
typename EOT::Fitness f = parents[idx].fitness();
f.setWorth(rank + niche_count);
parents[ idx ].fitness(f);
}
}
private :
double nicheSize;
eoFrontSorter<EOT> sorter;
};
#endif