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

new organisation of adaptive mechanisms

parent 2dca8982
No related branches found
No related tags found
No related merge requests found
......@@ -41,8 +41,9 @@ using namespace representation::permutation::problems::fsp;
#include "opt/singleSolution/localsearch/coolingSchedule/SimpleCoolingSchedule.h"
#include "opt/singleSolution/localsearch/LocalSearch.h"
#include "opt/singleSolution/localsearch/SimulatedAnnealing.h"
#include "opt/criterion/TimeCriterion.h"
#include "opt/adaptive/TimeWindow.h"
#include "opt/adaptive/ChangeIfSlowImprovementWindow.h"
#include "util/TimerHelper.h"
......@@ -76,6 +77,7 @@ int main(void) {
std::cout << sol << std::endl;
SOL sol2 = sol ; // duplicate solution
SOL sol3 = sol ; // duplicate solution
opt::singleSolution::localsearch::SimulatedAnnealing<SOL> *sa;
......@@ -108,6 +110,7 @@ int main(void) {
std::cout << "*************** Adaptive Part ************" << std::endl;
// Step 1 : creation of the algorithm (once time)
neighbor_type = "swap";
sa = createAlgorithm(neighbor_type, neighborhood_type, neighborhood_explorer,
......@@ -119,7 +122,7 @@ int main(void) {
// Step 2 : define functions that will modify the configuration of the algorithm during the process
// remark : any box of the algorithm is updatable dynamically, here illustrated with neighbor boxes
util::TimerHelper timer2 ;
//util::TimerHelper timer2 ;
representation::permutation::neighborhood::neighbor::ShiftNeighbor<SOL> shiftNeighbor;
std::function<void(opt::singleSolution::localsearch::SimulatedAnnealing<SOL>&)> setToShift = [&](opt::singleSolution::localsearch::SimulatedAnnealing<SOL> &_sa) {
opt::singleSolution::neighborhood::explorer::NeighborhoodExplorer<SOL> *ne ;
......@@ -143,11 +146,13 @@ int main(void) {
for (unsigned long long int i = 1 ; i<=vec_functions.size();i++) durations.push_back(criterion_length) ;
// Step 4, encapsulation of the algorithm to the adaptive time windows
opt::adaptive::TimeWindow<SOL,opt::singleSolution::localsearch::SimulatedAnnealing<SOL> > timeWindow(*sa, durations, vec_functions);
opt::adaptive::TimeWindow<SOL,opt::singleSolution::localsearch::SimulatedAnnealing<SOL> > timeWindow(*sa, vec_functions, durations);
std::cout << "INITIAL SOLUTION AFTER NEH" << std::endl;
std::cout << sol2 << std::endl;
std::cout << "using TimeWindow strategy during " << vec_functions.size()*criterion_length << std::endl;
std::cout << "every " << criterion_length <<" seconds, alternate the neighbor operators: swap and shift" << std::endl;
timeWindow(sol2);
......@@ -156,6 +161,57 @@ int main(void) {
eval(sol2);
std::cout << sol2 << std::endl;
/****************************************************************/
/* Using EvalSwitchWindow adaptive strategy */
/****************************************************************/
// Step 1 : creation of the algorithm (once time)
neighbor_type = "swap";
sa = createAlgorithm(neighbor_type, neighborhood_type, neighborhood_explorer,
eval, sol3,
perturbation_strategy, perturbation_strength,
sa_k,
criterion_strategy, 4*criterion_length);
// Step 2 : define functions that will modify the configuration of the algorithm during the process
// remark : any box of the algorithm is updatable dynamically, here illustrated with neighbor boxes
util::TimerHelper timer2 ;
//representation::permutation::neighborhood::neighbor::ShiftNeighbor<SOL> shiftNeighbor;
std::function<void(opt::singleSolution::localsearch::SimulatedAnnealing<SOL>&)> setToShift2 = [&](opt::singleSolution::localsearch::SimulatedAnnealing<SOL> &_sa) {
opt::singleSolution::neighborhood::explorer::NeighborhoodExplorer<SOL> *ne ;
ne = dynamic_cast<opt::singleSolution::neighborhood::explorer::NeighborhoodExplorer<SOL> *>(_sa.getAlgorithm()) ;
ne->getNeighborhood()->setNeighbor(shiftNeighbor);
std::cout << "setToShift" <<std::endl ;
};
//representation::permutation::neighborhood::neighbor::SwapNeighbor<SOL> swapNeighbor;
std::function<void(opt::singleSolution::localsearch::SimulatedAnnealing<SOL>&)> setToSwap2 = [&](opt::singleSolution::localsearch::SimulatedAnnealing<SOL> &_sa) {
opt::singleSolution::neighborhood::explorer::NeighborhoodExplorer<SOL> *ne ;
ne = dynamic_cast<opt::singleSolution::neighborhood::explorer::NeighborhoodExplorer<SOL> *>(_sa.getAlgorithm()) ;
ne->getNeighborhood()->setNeighbor(shiftNeighbor);
std::cout << "setToSwap" << std::endl ;
};
// Step 3 : store the functions in a vector in the right order and fix a time where these functions are called
std::vector<std::function<void(opt::singleSolution::localsearch::SimulatedAnnealing<SOL>&)>> vec_functions2 = {setToSwap,setToShift};
// Step 4, encapsulation of the algorithm to the adaptive time windows
opt::adaptive::ChangeIfSlowImprovementWindow<SOL,opt::singleSolution::localsearch::SimulatedAnnealing<SOL> > adaptiveWindow(*sa, vec_functions2, 4, 5, 10,eval);
std::cout << "INITIAL SOLUTION AFTER NEH" << std::endl;
std::cout << sol3 << std::endl;
std::cout << "using TimeWindow strategy during " << vec_functions.size()*criterion_length << std::endl;
std::cout << "every " << criterion_length <<" seconds, alternate the neighbor operators: swap and shift" << std::endl;
adaptiveWindow(sol3);
std::cout << "FINAL SOLUTION" << std::endl;
eval(sol3);
std::cout << sol3 << std::endl;
return 0;
}
......
......@@ -111,7 +111,7 @@ int main(void) {
for (unsigned long long int i = 1 ; i<=functions.size();i++) durations.push_back(criterion_length) ;
// encapsulation of the algorithm with the adaptive timewindow object
opt::adaptive::TimeWindow<SOL, opt::singleSolution::localsearch::HillClimbing<SOL>> timeWindow(*algo, durations, functions);
opt::adaptive::TimeWindow<SOL, opt::singleSolution::localsearch::HillClimbing<SOL>> timeWindow(*algo, functions, durations);
std::cout << "ADAPTIVE VERSION" << std::endl ;
std::cout << "INITIAL SOLUTION" << std::endl;
......
......@@ -122,7 +122,7 @@ int main(void) {
for (unsigned long long int i = 1 ; i<=functions.size();i++) durations.push_back(criterion_length) ;
// encapsulation of the algorithm with the adaptive timewindow object
opt::adaptive::TimeWindow<SOL, opt::singleSolution::localsearch::HillClimbing<SOL>> timeWindow(*algo, durations, functions);
opt::adaptive::TimeWindow<SOL, opt::singleSolution::localsearch::HillClimbing<SOL>> timeWindow(*algo, functions, durations);
std::cout << "ADAPTIVE VERSION" << std::endl ;
std::cout << "INITIAL SOLUTION" << std::endl;
......
/***************************************************************************************
* MH-Builder, a framework for designing adaptive metaheuristics *
* for single and multi-objective optimization. *
* (c) 2019 University of Lille, CNRS *
* *
* This program is free software; you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or (at *
* your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
* for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
****************************************************************************************
Authors: Olivier Caron and additional contributors (see Authors)
****************************************************************************************/
#ifndef MH_BUILDER_ADAPTIVE_WINDOW_H
#define MH_BUILDER_ADAPTIVE_WINDOW_H
#include "core/Algorithm.h"
#include <functional>
#include <iostream>
#include "opt/criterion/TimeCriterion.h"
namespace opt::adaptive {
/**
* abstract class for all adaptive strategies of a given algorithm
* @tparam IN the type of a solution
* @tparam ALGO the type of the algorithm
*/
template<typename IN, typename ALGO>
class AdaptiveWindow : public core::Algorithm<IN> {
public:
/**
* Initialisation
* @param _algorithm the algorithm
* @param _functions the vector of functions that modify the structure of the algorithm
*/
AdaptiveWindow(ALGO &_algorithm, std::vector<std::function<void(ALGO &)>> &_functions) :
algorithm(_algorithm), functions(_functions) {}
/**
* run the algorithm, change dynamically the structure of the algorithm thanks to
* the vector of functions
* @param _in the initial solution
*/
virtual void operator()(IN &_in) = 0 ;
protected:
ALGO &algorithm;
std::vector<std::function<void(ALGO &)>> &functions;
};
}
#endif //MH_BUILDER_ADAPTIVE_WINDOW_H
/***************************************************************************************
* MH-Builder, a framework for designing adaptive metaheuristics *
* for single and multi-objective optimization. *
* (c) 2019 University of Lille, CNRS *
* *
* This program is free software; you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or (at *
* your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
* for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
****************************************************************************************
Authors: Olivier Caron and additional contributors (see Authors)
****************************************************************************************/
#ifndef MH_BUILDER_CHANGE_IF_SLOW_IMPROVEMENT_WINDOW_H
#define MH_BUILDER_CHANGE_IF_SLOW_IMPROVEMENT_WINDOW_H
#include "core/Algorithm.h"
#include "core/Eval.h"
#include <functional>
#include <iostream>
#include "opt/criterion/TimeCriterion.h"
#include "opt/adaptive/AdaptiveWindow.h"
namespace opt::adaptive {
/**
* adaptive strategy that regularly modifies the structure of the algorithm
* if the solution does not improve by a given percentage
* @tparam IN the type of the solution
* @tparam ALGO the type of the algorithm
*/
template<typename IN, typename ALGO>
class ChangeIfSlowImprovementWindow : public opt::adaptive::AdaptiveWindow<IN,ALGO> {
public:
/**
* Initialisation of the Eval Switch Adaptive Strategy
* @param _algorithm the given algorithm
* @param _functions the set of alternative functions which modify the structure of the algorithm
* @param _duration the elapsed time where the switch test is performed in seconds
* @param _improvement_percentage the percentage that determines if a switch is required
* @param _max_iterations the maximum number of iterations
* @param _eval The eval function
*/
ChangeIfSlowImprovementWindow(ALGO &_algorithm, std::vector<std::function<void(ALGO &)>> &_functions,
int _duration, int _improvement_percentage, int _max_iterations, core::Eval<IN> &_eval)
: opt::adaptive::AdaptiveWindow<IN,ALGO>(_algorithm, _functions),
duration(_duration),improvement_percentage(_improvement_percentage),
max_iterations(_max_iterations), eval(_eval) {}
/**
* run the algorithm with the adaptive strategy
* @param _in the initial solution
*/
void operator()(IN &_in) {
// init phase
auto fitness_scalar_value = _in.fitness().scalar() ;
int counter=1 ; int select_function=0 ;
criterion::TimeCriterion<IN> timeCriterion(duration*1000);
timeCriterion.init();
// perform algorithm with the specific adaptive strategy
while (counter <= this->max_iterations ) {
auto current_fitness_value = _in.fitness().scalar() ;
std::cout << "Iteration no " << counter << ": " << fitness_scalar_value << " - " << current_fitness_value << std::endl;
if (abs(fitness_scalar_value-current_fitness_value) <
fitness_scalar_value/this->improvement_percentage) {
std::cout << "modify algorithm !" << (select_function % this->functions.size()) << std::endl ;
fitness_scalar_value = current_fitness_value ;
this->functions[select_function % this->functions.size()](this->algorithm);
select_function++ ;
} else std::cout << "NO modify algorithm !" << std::endl;
timeCriterion.init();
this->algorithm(_in, timeCriterion);
counter++ ;
}
}
protected:
int duration ;
int improvement_percentage ;
int max_iterations ;
core::Eval<IN> &eval ;
};
}
#endif //MH_BUILDER_CHANGE_IF_SLOW_IMPROVEMENT_WINDOW_H
......@@ -19,45 +19,59 @@
Authors: Lucien Mousin and additional contributors (see Authors)
****************************************************************************************/
#ifndef MH_BUILDER_TIMEWINDOW_H
#define MH_BUILDER_TIMEWINDOW_H
#ifndef MH_BUILDER_TIME_WINDOW_H
#define MH_BUILDER_TIME_WINDOW_H
#include "core/Algorithm.h"
#include <functional>
#include <iostream>
#include "opt/criterion/TimeCriterion.h"
#include "opt/adaptive/AdaptiveWindow.h"
namespace opt {
namespace adaptive {
namespace opt::adaptive {
/**
* adaptive strategy which modifies the structure of the algorithm
* at different times indicated by the ‘durations’ vector
* @tparam IN the type of the solution
* @tparam ALGO the type of the algorithm
*/
template<typename IN, typename ALGO>
class TimeWindow : public core::Algorithm<IN> {
class TimeWindow : public opt::adaptive::AdaptiveWindow<IN,ALGO> {
public:
TimeWindow(ALGO &_algorithm, std::vector<long long int> &_durations,
std::vector <std::function<void(ALGO &)>> &_functions) :
algorithm(_algorithm),
durations(_durations),
functions(_functions) {
if (durations.size() != _functions.size()) {
/**
* Initialisation of the Time Adaptive Strategy
* @param _algorithm the given algorithm
* @param _functions the vector of functions which modify the structure of the algorithm
* @param _durations the vector of elapsed times to adapt the algorithm
*/
TimeWindow(ALGO &_algorithm, std::vector<std::function<void(ALGO &)>> &_functions,
std::vector<long long int> &_durations)
: opt::adaptive::AdaptiveWindow<IN,ALGO>(_algorithm, _functions),durations(_durations){
if (this->durations.size() != _functions.size()) {
std::cerr << "durations vector and functions vector must be the same size !!";
exit(0);
}
}
/**
* run the algorithm with the adaptive strategy
* @param _in the initial solution
*/
void operator()(IN &_in) {
for (unsigned long long int i = 0; i < durations.size(); i++) {
criterion::TimeCriterion <IN> timeCriterion(durations[i]);
functions[i](algorithm);
for (unsigned long long int i = 0; i < this->durations.size(); i++) {
criterion::TimeCriterion<IN> timeCriterion(this->durations[i]);
this->functions[i](this->algorithm);
timeCriterion.init();
algorithm(_in, timeCriterion);
this->algorithm(_in, timeCriterion);
}
}
protected:
ALGO &algorithm;
std::vector<long long int> &durations;
std::vector <std::function<void(ALGO &)>> &functions;
};
}
}
#endif //MH_BUILDER_TIMEWINDOW_H
#endif //MH_BUILDER_TIME_WINDOW_H
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment