Skip to content
Snippets Groups Projects
Commit 1ad07dcf authored by Caron Olivier's avatar Caron Olivier
Browse files

archive checkpoint refactoring

parent f6f5d1e9
Branches
No related tags found
No related merge requests found
Pipeline #4541 failed
......@@ -82,7 +82,7 @@ int main() {
population.clear();
// init population of 200 individuals
for(unsigned long long int i=0; i<200;++i){
SOL solution(512);
SOL solution(300);
solution.shuffle() ;
std::cout << solution << std::endl ;
NSGA2_SOL decorator(solution) ; nsga2_eval(decorator);
......@@ -130,8 +130,10 @@ int main() {
std::cout << "Result: SUCCESS, " << 1;
std::cout << ", [" << hypervolume << ", " << spread << "], " << seed << std::endl;
matplotlibcpp::named_plot("Obj 1", archiveCheckpoint.getTimeValues(), archiveCheckpoint.getBestValues(0));
matplotlibcpp::named_plot("Obj 2", archiveCheckpoint.getTimeValues(), archiveCheckpoint.getBestValues(1));
matplotlibcpp::named_plot("Best Obj 1 (t)", archiveCheckpoint.getTimeValues(), archiveCheckpoint.getValues(0));
matplotlibcpp::named_plot("Best Obj 2 (t)", archiveCheckpoint.getTimeValues(), archiveCheckpoint.getValues(1));
matplotlibcpp::named_plot("Best Obj 1 (0->t)", archiveCheckpoint.getTimeValues(), archiveCheckpoint.getBestValues(0));
matplotlibcpp::named_plot("Best Obj 2 (0->t)", archiveCheckpoint.getTimeValues(), archiveCheckpoint.getBestValues(1));
matplotlibcpp::xlim(0, nbMilliSeconds);
matplotlibcpp::title("Genetic Algorithm");
matplotlibcpp::xlabel("Time (seconds)");
......@@ -139,27 +141,7 @@ int main() {
matplotlibcpp::legend();
matplotlibcpp::show();
int secondsCounter=1 ;
unsigned long long int indFirst=0 ;
vector<vector<double>> results;
for (unsigned long long int i=0; i < archiveCheckpoint.getTimeValues().size() ;i++) {
if (archiveCheckpoint.getTimeValues()[i]<(secondsCounter*1000)) continue ;
else {
// Starting and Ending iterators
auto start = archiveCheckpoint.getValues(0).begin() + indFirst;
auto end = archiveCheckpoint.getValues(0).begin()+i;
vector<double> v(start, end); results.push_back(v) ;
secondsCounter++; indFirst=i ;
}
}
matplotlibcpp::boxplot(results);
matplotlibcpp::title("Genetic Algorithm");
matplotlibcpp::xlabel("Time (seconds)");
matplotlibcpp::ylabel("fitness first objective");
matplotlibcpp::show();
return 0;
}
......@@ -121,8 +121,8 @@ int main(void) {
std::cout << "And the best solution is: " << population[0].fitness() << std::endl ;
std::cout << "Number of generations : " << ga.getNumberOfGenerations() << std::endl ;
matplotlibcpp::named_plot("Obj 1", archiveCheckpoint.getTimeValues(), archiveCheckpoint.getValues(0));
//matplotlibcpp::named_plot("Obj 2", archiveCheckpoint.getTimeValues(), archiveCheckpoint.getValues(1));
matplotlibcpp::named_plot("best Obj (t)", archiveCheckpoint.getTimeValues(), archiveCheckpoint.getValues(0));
matplotlibcpp::named_plot("best Obj (0->t)", archiveCheckpoint.getTimeValues(), archiveCheckpoint.getBestValues(0));
matplotlibcpp::xlim(0, 5000);
matplotlibcpp::title("Genetic Algorithm");
matplotlibcpp::xlabel("Time (milliseconds)");
......
......@@ -131,7 +131,7 @@ int main() {
matplotlibcpp::xlim(0, 5000);
matplotlibcpp::title("Genetic Algorithm");
matplotlibcpp::xlabel("Time (milliseconds)");
matplotlibcpp::ylabel("fitness objective");
matplotlibcpp::ylabel("objective values");
matplotlibcpp::legend();
matplotlibcpp::show();
return 0;
......
......@@ -30,8 +30,9 @@ using namespace std ;
namespace opt::checkpoint {
/**
* Class that allows to store checkpoints, this class is suitable for archive
* for one checkpoint, stored values are :
* (1) the best objective values from the archive at instant t,
* At each checkpoint, the current archive and time checkpoint are stored
* At the end of a running process, the archive can provides :
* (1) for one given objective, the best objective values from the archive at instant t,
* (2) the preservation of the best objective values from t0 to t
* (3) the elapsed time t
* @tparam SOL : the type of the solution
......@@ -43,15 +44,23 @@ namespace opt::checkpoint {
typedef typename SOL::FITNESS FIT;
typedef typename FIT::VALUE_TYPE VALUE;
protected:
std::vector<std::vector<VALUE>> values; // objective values
TimeCheckpoint<SOL> time_checkpoint; // elapsed time values
std::vector<std::vector<VALUE>> bestValues ;// best values
std::vector<std::vector<std::vector<VALUE>>> archive_checkpoint ;
// archive is a vector of checkpoints, archive[i] corresponds to one checkpoint
// archive[i][j] corresponds to a vector of objective values for objective j
// archive[i][j][k] corresponds to an objective value
TimeCheckpoint<double> time_checkpoint; // elapsed time values
unsigned long long int numberOfObjectives ;
bool isMaximisationFitness ;
unsigned long long int frequency ; // the minimum time in milliseconds between stored checkpoints
public:
/**
* constructor, set inner values
* @param frequency the minimum time in milliseconds between stored checkpoints
*/
ArchiveCheckpoint() : values(0), bestValues(0) {}
ArchiveCheckpoint(unsigned long long int _frequency = 1000) : archive_checkpoint(0),
numberOfObjectives(1), isMaximisationFitness(true), frequency(_frequency) {}
/**
* default destructor
......@@ -60,18 +69,19 @@ namespace opt::checkpoint {
/**
* initialisation of inner values
* @param _sol , here unused
* @param _sol
*/
void init(const ARCHIVE &_sol);
/**
* add a checkpoint, store the best solutions for all objectives
* @param _sol
* add a checkpoint if the elapsed time between the previous checkpoint >= frequency
* store objective values of the archive for all objectives
* @param _sol the given archive
*/
void operator()(const ARCHIVE &_sol);
/**
* provide objective values
* provide objective values of all checkpoints
* @param unsigned long long int the objective number
* @return vector
*/
......@@ -88,6 +98,18 @@ namespace opt::checkpoint {
* @return
**/
virtual std::vector<double> &getTimeValues();
private:
/**
* return true if v1 is better than v2
* @param v1
* @param v2
*/
bool isBetter(VALUE v1, VALUE v2) {
if (this->isMaximisationFitness) return v1 > v2 ;
else return v1 < v2 ;
}
};
#include "ArchiveCheckpoint.tpp"
......
......@@ -28,48 +28,70 @@
*/
template<typename ARCHIVE>
void ArchiveCheckpoint<ARCHIVE>::init(const ARCHIVE &_arch) {
if (_arch.size() > 0) {
auto oneSol = _arch[0];
auto nbObjectives = oneSol.fitness().objectives().size();
this->values.resize(nbObjectives) ;
this->bestValues.resize(nbObjectives) ;
this->time_checkpoint.init(_arch.getBestSolutionForEachObjective()[0]);
this->numberOfObjectives = oneSol.fitness().objectives().size();
this->isMaximisationFitness = oneSol.fitness().isMaximisationFitness();
//this->values.resize(nbObjectives) ;
//this->bestValues.resize(nbObjectives) ;
this->time_checkpoint.init(0.0);
} else throw std::runtime_error("ArchiveCheckpoint::init(_arch) : Error, the archive is empty ");
}
/**
* add a checkpoint
* @param _arch store the first objective of the fitness of the best sol of the archive
* add a checkpoint if the elapsed time between the previous checkpoint >= frequency
* store objective values of the archive for all objectives
* @param _sol the given archive
*/
template<typename ARCHIVE>
void ArchiveCheckpoint<ARCHIVE>::operator()(const ARCHIVE &_arch) {
auto bests = _arch.getBestSolutionForEachObjective();
auto nbObjectives = this->values.size();
for (unsigned long long int i = 0; i < nbObjectives; i++) {
ArchiveCheckpoint<ARCHIVE>::VALUE current = bests[i].fitness().objectives()[i] ;
this->values[i].push_back(current);
if (this->bestValues[i].size()==0) this->bestValues[i].push_back(current) ;
else this->bestValues[i].push_back(this->bestValues[i].back() >current ? this->bestValues[i].back() : current) ;
if ((this->archive_checkpoint.size()==0 // first checkpoint or delay between last checkpoint >= frequency
|| (this->time_checkpoint.getElapsedTime()-this->time_checkpoint.getValues().back()) >= this->frequency)) {
this->archive_checkpoint.resize(this->archive_checkpoint.size() + 1); // adding one element
this->archive_checkpoint.back().resize(this->numberOfObjectives);
for (SOL sol: _arch) {
for (unsigned long long int obj = 0; obj < this->numberOfObjectives; obj++)
this->archive_checkpoint.back()[obj].push_back(sol.fitness().objectives()[obj]);
}
this->time_checkpoint(bests[0]); // a unique time_checkpoint for all objectives
this->time_checkpoint(0.0); // a unique time_checkpoint for all objectives
}
}
/**
* provide objective values
* provide best objective values of all checkpoints for a given objective
* here the best objective value of a checkpoint i can be worst than the objective value of checkpoint i-1
* @param unsigned long long int the objective number
* @return vector
*/
template<typename ARCHIVE>
std::vector<typename ArchiveCheckpoint<ARCHIVE>::VALUE> ArchiveCheckpoint<ARCHIVE>::getValues(unsigned long long int objNum) {
return this->values[objNum];
std::vector<typename ArchiveCheckpoint<ARCHIVE>::VALUE>
ArchiveCheckpoint<ARCHIVE>::getValues(unsigned long long int objNum) {
std::vector<typename ArchiveCheckpoint<ARCHIVE>::VALUE> result;
for (auto checkpoint: this->archive_checkpoint) {
typename ArchiveCheckpoint<ARCHIVE>::VALUE best = checkpoint[objNum][0];
for (auto objValue: checkpoint[objNum])
if (this->isBetter(objValue, best)) best = objValue;
result.push_back(best);
}
return result;
}
/**
* provide best objective values
* provide the evolution of best memorised objective values found
* @param unsigned long long int the objective number
* @return vector
*/
template<typename ARCHIVE>
std::vector<typename ArchiveCheckpoint<ARCHIVE>::VALUE> ArchiveCheckpoint<ARCHIVE>::getBestValues(unsigned long long int objNum) {
return this->bestValues[objNum];
std::vector<typename ArchiveCheckpoint<ARCHIVE>::VALUE>
ArchiveCheckpoint<ARCHIVE>::getBestValues(unsigned long long int objNum) {
std::vector<typename ArchiveCheckpoint<ARCHIVE>::VALUE> result = this->getValues(objNum);
for (unsigned long long int i = 1; i < result.size(); i++)
if (this->isBetter(result[i - 1], result[i])) {
result[i] = result[i - 1];
}
return result;
}
......
......@@ -59,6 +59,12 @@ namespace opt::checkpoint {
* @return vector of elapsed times
*/
std::vector<double> &getValues() ;
/**
* provide the elapsed time since the initialisation
* @return
*/
double getElapsedTime() ;
};
#include "TimeCheckpoint.tpp"
}
......
......@@ -32,7 +32,7 @@ TimeCheckpoint<SOL>::TimeCheckpoint() : values(0) {
/**
* initialisation of inner values
* @param _sol , here unused
*/
**/
template<typename SOL>
void TimeCheckpoint<SOL>::init([[maybe_unused]] const SOL &_sol) {
values.clear();
......@@ -42,7 +42,7 @@ void TimeCheckpoint<SOL>::init([[maybe_unused]] const SOL &_sol) {
/**
* add a checkpoint
* @param _sol here unused
*/
**/
template<typename SOL>
void TimeCheckpoint<SOL>::operator()([[maybe_unused]] const SOL &_sol) {
timerHelper.update();
......@@ -52,8 +52,18 @@ void TimeCheckpoint<SOL>::operator()([[maybe_unused]] const SOL &_sol) {
/**
* provides all stored checkpoint values
* @return vector of elapsed times
*/
**/
template<typename SOL>
std::vector<double> &TimeCheckpoint<SOL>::getValues() {
return values;
}
/**
* provide the elapsed time since the initialisation
* @return
**/
template<typename SOL>
double TimeCheckpoint<SOL>::getElapsedTime() {
timerHelper.update();
return timerHelper.elapsedTime();
}
\ No newline at end of file
......@@ -40,7 +40,7 @@ namespace opt {
/**
* Compute the normalized hypervolume metric according to an archive
* @param _archive
* @return the normalized spread
* @return the normalized hypervolume
*/
double operator()(const ARCHIVE &_archive) {
if (_archive.size() < 1)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment