diff --git a/branches/paradiseo-moeo-1.0/tutorials/lesson1/FlowShop.h b/branches/paradiseo-moeo-1.0/tutorials/lesson1/FlowShop.h new file mode 100644 index 000000000..fbddadacd --- /dev/null +++ b/branches/paradiseo-moeo-1.0/tutorials/lesson1/FlowShop.h @@ -0,0 +1,114 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// FlowShop.h +// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2007 +/* + This library... + + Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr + */ +//----------------------------------------------------------------------------- + +#ifndef FLOWSHOP_H_ +#define FLOWSHOP_H_ + +#include +#include +#include + + +/** + * definition of the objective vector for multi-objective flow-shop problems + */ +typedef moeoObjectiveVectorDouble FlowShopObjectiveVector; + + +/** + * Structure of the genotype for the flow-shop scheduling problem + */ +class FlowShop: public MOEO { + +public: + + /** + * default constructor + */ + FlowShop() {} + + /** + * destructor + */ + virtual ~FlowShop() {} + + /** + * class name + */ + virtual string className() const { + return "FlowShop"; + } + + /** + * set scheduling vector + * @param vector & _scheduling the new scheduling to set + */ + void setScheduling(vector & _scheduling) { + scheduling = _scheduling; + } + + /** + * get scheduling vector + */ + const vector & getScheduling() const { + return scheduling; + } + + /** + * printing... + */ + void printOn(ostream& _os) const { + // fitness + MOEO::printOn(_os); + // size + _os << scheduling.size() << "\t" ; + // scheduling + for (unsigned i=0; i::readFrom(_is); + // size + unsigned size; + _is >> size; + // scheduling + scheduling.resize(size); + bool tmp; + for (unsigned i=0; i> tmp; + scheduling[i] = tmp; + } + } + + + bool operator==(const FlowShop& _other) const { return scheduling == _other.getScheduling(); } + bool operator!=(const FlowShop& _other) const { return scheduling != _other.getScheduling(); } + bool operator< (const FlowShop& _other) const { return scheduling < _other.getScheduling(); } + bool operator> (const FlowShop& _other) const { return scheduling > _other.getScheduling(); } + bool operator<=(const FlowShop& _other) const { return scheduling <= _other.getScheduling(); } + bool operator>=(const FlowShop& _other) const { return scheduling >= _other.getScheduling(); } + + +private: + + /** scheduling (order of operations) */ + std::vector scheduling; + +}; + + +#endif /*FLOWSHOP_H_*/ diff --git a/branches/paradiseo-moeo-1.0/tutorials/lesson1/FlowShopBenchmarkParser.h b/branches/paradiseo-moeo-1.0/tutorials/lesson1/FlowShopBenchmarkParser.h new file mode 100644 index 000000000..7cc808409 --- /dev/null +++ b/branches/paradiseo-moeo-1.0/tutorials/lesson1/FlowShopBenchmarkParser.h @@ -0,0 +1,140 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// FlowShopBenchmarkParser.h +// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2007 +/* + This library... + + Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr + */ +//----------------------------------------------------------------------------- + +#ifndef FLOWSHOPBENCHMARKPARSER_H_ +#define FLOWSHOPBENCHMARKPARSER_H_ +#include +#include + +/** Web site to download benchmarks */ +const static std::string BENCHMARKS_WEB_SITE = "www.lifl.fr/~basseur/BenchsUncertain/"; + + +/** + * Class to handle parameters of a flow-shop instance from a benchmark file + * benchmark files are available at www.lifl.fr/~basseur/BenchsUncertain/ + */ +class FlowShopBenchmarkParser { + +public: + + /** + * constructor + * @param const string _benchmarkFileName the name of the benchmark file + */ + FlowShopBenchmarkParser(const string _benchmarkFileName) { + init(_benchmarkFileName); + } + + /** + * the number of machines + */ + const unsigned getM() { + return M; + } + + /** + * the number of jobs + */ + const unsigned getN() { + return N; + } + + /** + * the processing times + */ + const std::vector< std::vector > getP() { + return p; + } + + /** + * the due-dates + */ + const std::vector getD() { + return d; + } + + /** + * printing... + */ + void printOn(ostream& _os) const { + _os << "M=" << M << " N=" << N << endl; + _os << "*** processing times" << endl; + for (unsigned i=0; i > p; + /** d[j] = due-date of the job j */ + std::vector d; + + + /** + * Initialisation of the parameters with the data contained in the benchmark file + * @param const string _benchmarkFileName the name of the benchmark file + */ + void init(const string _benchmarkFileName) { + string buffer; + string::size_type start, end; + ifstream inputFile(_benchmarkFileName.data(), ios::in); + // opening of the benchmark file + if (! inputFile) + cerr << "*** ERROR : Unable to open the benchmark file '" << _benchmarkFileName << "'" << endl; + // number of jobs (N) + getline(inputFile, buffer, '\n'); + N = atoi(buffer.data()); + // number of machines M + getline(inputFile, buffer, '\n'); + M = atoi(buffer.data()); + // initial and current seeds (not used) + getline(inputFile, buffer, '\n'); + // processing times and due-dates + p = std::vector< std::vector > (M,N); + d = std::vector (N); + // for each job... + for (unsigned j=0 ; j j) + getline(inputFile, buffer, '\n'); + // due-date of the job j + getline(inputFile, buffer, '\n'); + d[j] = atoi(buffer.data()); + // processing times of the job j on each machine + getline(inputFile, buffer, '\n'); + start = buffer.find_first_not_of(" "); + for (unsigned i=0 ; i +// for the creation of an evaluator +#include "make_eval_FlowShop.h" +// for the creation of an initializer +#include "make_genotype_FlowShop.h" +// for the creation of the variation operators +#include "make_op_FlowShop.h" +// how to initialize the population +#include +// the stopping criterion +#include +// outputs (stats, population dumps, ...) +#include +// evolution engine (selection and replacement) +#include +// simple call to the algo +#include +// checks for help demand, and writes the status file and make_help; in libutils +void make_help(eoParser & _parser); +/* FLOW-SHOP */ +// definition of representation +#include "FlowShop.h" + + +int main(int argc, char* argv[]) { + try { + + eoParser parser(argc, argv); // for user-parameter reading + eoState state; // to keep all things allocated + + + + + + /*** the representation-dependent things ***/ + + // The fitness evaluation + eoEvalFuncCounter& eval = do_make_eval(parser, state); + // the genotype (through a genotype initializer) + eoInit& init = do_make_genotype(parser, state); + // the variation operators + eoGenOp& op = do_make_op(parser, state); + + + + + + /*** the representation-independent things ***/ + + // initialization of the population + eoPop& pop = do_make_pop(parser, state, init); + // definition of the archive + moeoArchive arch; + // stopping criteria + eoContinue& term = do_make_continue_moeo(parser, state, eval); + // output + eoCheckPoint& checkpoint = do_make_checkpoint_moeo(parser, state, eval, term, pop, arch); + // algorithm + eoAlgo& algo = do_make_ea_moeo(parser, state, eval, checkpoint, op, arch); + + + + + + /*** Go ! ***/ + + // help ? + make_help(parser); + + // first evalution + apply(eval, pop); + + pop.sort(); + arch.update(pop); + + // printing of the initial population + cout << "Initial Population\n"; + pop.sortedPrintOn(cout); + cout << endl; + + // run the algo + do_run(algo, pop); + + // printing of the final population + cout << "Final Population\n"; + pop.sortedPrintOn(cout); + cout << endl; + + // printing of the final archive + cout << "Final Archive\n"; + arch.sortedPrintOn(cout); + cout << endl; + + + + } catch(exception& e) { + cout << e.what() << endl; + } + return EXIT_SUCCESS; +} diff --git a/branches/paradiseo-moeo-1.0/tutorials/lesson1/FlowShopEval.h b/branches/paradiseo-moeo-1.0/tutorials/lesson1/FlowShopEval.h new file mode 100644 index 000000000..049474001 --- /dev/null +++ b/branches/paradiseo-moeo-1.0/tutorials/lesson1/FlowShopEval.h @@ -0,0 +1,129 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// FlowShopEval.h +// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2007 +/* + This library... + + Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr + */ +//----------------------------------------------------------------------------- + +#ifndef FLOWSHOPEVAL_H_ +#define FLOWSHOPEVAL_H_ + +#include "FlowShop.h" +#include + +/** + * Functor + * Computation of the multi-objective evaluation of a FlowShop object + */ +class FlowShopEval : public moeoEvalFunc { + +public: + + /** + * constructor + * @param _M the number of machines + * @param _N the number of jobs to schedule + * @param _p the processing times + * @param _d the due dates + */ + FlowShopEval(const unsigned _M, const unsigned _N, const vector< vector > & _p, const vector & _d) : + M(_M), N (_N), p(_p), d(_d){ + + unsigned nObjs = 2; + std::vector bObjs(nObjs, true); + moeoObjectiveVectorTraits::setup(nObjs, bObjs); + } + + + + /** + * computation of the multi-objective evaluation of an eoFlowShop object + * @param FlowShop & _eo the FlowShop object to evaluate + */ + void operator()(FlowShop & _eo) { + FlowShopObjectiveVector objVector; + objVector[0] = tardiness(_eo); + objVector[1] = makespan(_eo); + _eo.objectiveVector(objVector); + } + + + + + +private: + + /** number of machines */ + unsigned M; + /** number of jobs */ + unsigned N; + /** p[i][j] = processing time of job j on machine i */ + std::vector< std::vector > p; + /** d[j] = due-date of the job j */ + std::vector d; + + + + /** + * computation of the makespan + * @param FlowShop _eo the FlowShop object to evaluate + */ + double makespan(FlowShop _eo) { + // the scheduling to evaluate + vector scheduling = _eo.getScheduling(); + // completion times computation for each job on each machine + // C[i][j] = completion of the jth job of the scheduling on the ith machine + std::vector< std::vector > C = completionTime(_eo); + // fitness == C[M-1][scheduling[N-1]]; + return C[M-1][scheduling[N-1]]; + } + + + + /** + * computation of the tardiness + * @param _eo the FlowShop object to evaluate + */ + double tardiness(FlowShop _eo) { + // the scheduling to evaluate + vector scheduling = _eo.getScheduling(); + // completion times computation for each job on each machine + // C[i][j] = completion of the jth job of the scheduling on the ith machine + std::vector< std::vector > C = completionTime(_eo); + // tardiness computation + unsigned long sum = 0; + for (unsigned j=0 ; j > completionTime(FlowShop _eo) { + vector scheduling = _eo.getScheduling(); + std::vector< std::vector > C(M,N); + C[0][scheduling[0]] = p[0][scheduling[0]]; + for (unsigned j=1; j +#include "FlowShop.h" + +/** + * Functor + * Initialisation of a random genotype built by the default constructor of the eoFlowShop class + */ +class FlowShopInit: public eoInit { + +public: + + /** + * constructor + * @param const unsigned _N the number of jobs to schedule + */ + FlowShopInit(const unsigned _N) { + N = _N; + } + + /** + * randomize a genotype + * @param FlowShop & _genotype a genotype that has been default-constructed + */ + void operator()(FlowShop & _genotype) { + // scheduling vector + vector scheduling(N); + // initialisation of possible values + vector possibles(N); + for(unsigned i=0 ; i +#include "FlowShop.h" + +/** + * Functor + * Quadratic crossover operator for flow-shop (modify the both genotypes) + */ +class FlowShopOpCrossoverQuad: public eoQuadOp { + +public: + + /** + * default constructor + */ + FlowShopOpCrossoverQuad() {} + + /** + * the class name (used to display statistics) + */ + string className() const { + return "FlowShopOpCrossoverQuad"; + } + + /** + * eoQuad crossover - _genotype1 and _genotype2 are the (future) offspring, i.e. _copies_ of the parents + * @param FlowShop & _genotype1 the first parent + * @param FlowShop & _genotype2 the second parent + */ + bool operator()(FlowShop & _genotype1, FlowShop & _genotype2) { + bool oneAtLeastIsModified; + + // parents + vector parent1 = _genotype1.getScheduling(); + vector parent2 = _genotype2.getScheduling(); + + // computation of the 2 random points + unsigned point1, point2; + do { + point1 = rng.random(min(parent1.size(), parent2.size())); + point2 = rng.random(min(parent1.size(), parent2.size())); + } while (fabs((double) point1-point2) <= 2); + + // computation of the offspring + vector offspring1 = generateOffspring(parent1, parent2, point1, point2); + vector offspring2 = generateOffspring(parent2, parent1, point1, point2); + + // does at least one genotype has been modified ? + if ((parent1 != offspring1) || (parent2 != offspring2)) { + // update + _genotype1.setScheduling(offspring1); + _genotype2.setScheduling(offspring2); + // at least one genotype has been modified + oneAtLeastIsModified = true; + } + else { + // no genotype has been modified + oneAtLeastIsModified = false; + } + + // return 'true' if at least one genotype has been modified + return oneAtLeastIsModified; + } + + +private: + + /** + * generation of an offspring by a 2 points crossover + * @param vector _parent1 the first parent + * @param vector _parent2 the second parent + * @param unsigned_point1 the first point + * @param unsigned_point2 the second point + */ + vector generateOffspring(vector _parent1, vector _parent2, unsigned _point1, unsigned _point2) { + vector result = _parent1; + vector taken_values(result.size(), false); + if (_point1 > _point2) swap(_point1, _point2); + + /* first parent */ + for (unsigned i=0 ; i<=_point1 ; i++) { + // result[i] == _parent1[i] + taken_values[_parent1[i]] = true; + } + for (unsigned i=_point2 ; i +#include "FlowShop.h" + +/** + * Functor + * Exchange mutation operator for flow-shop + */ +class FlowShopOpMutationExchange: public eoMonOp { + +public: + + /** + * default constructor + */ + FlowShopOpMutationExchange() {} + + /** + * the class name (used to display statistics) + */ + string className() const { + return "FlowShopOpMutationExchange"; + } + + /** + * modifies the parent with an exchange mutation + * @param FlowShop & _genotype the parent genotype (will be modified) + */ + bool operator()(FlowShop & _genotype) { + bool isModified; + + // schedulings + vector initScheduling = _genotype.getScheduling(); + vector resultScheduling = _genotype.getScheduling(); + + // computation of the 2 random points + unsigned point1, point2; + do { + point1 = rng.random(resultScheduling.size()); + point2 = rng.random(resultScheduling.size()); + } while (point1 == point2); + + // swap + swap (resultScheduling[point1], resultScheduling[point2]); + + // update (if necessary) + if (resultScheduling != initScheduling) { + // update + _genotype.setScheduling(resultScheduling); + // the genotype has been modified + isModified = true; + } + else { + // the genotype has not been modified + isModified = false; + } + + // return 'true' if the genotype has been modified + return isModified; + } + +}; + +#endif /*FLOWSHOPOPMUTATIONEXCHANGE_H_*/ diff --git a/branches/paradiseo-moeo-1.0/tutorials/lesson1/FlowShopOpMutationShift.h b/branches/paradiseo-moeo-1.0/tutorials/lesson1/FlowShopOpMutationShift.h new file mode 100644 index 000000000..64949a549 --- /dev/null +++ b/branches/paradiseo-moeo-1.0/tutorials/lesson1/FlowShopOpMutationShift.h @@ -0,0 +1,86 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// FlowShopOpMutationShift.h +// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2007 +/* + This library... + + Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr + */ +//----------------------------------------------------------------------------- + +#ifndef FLOWSHOPOPMUTATIONSHIFT_H_ +#define FLOWSHOPOPMUTATIONSHIFT_H_ + +#include +#include "FlowShop.h" + +/** + * Functor + * Shift mutation operator for flow-shop + */ +class FlowShopOpMutationShift: public eoMonOp { + +public: + + /** + * default constructor + */ + FlowShopOpMutationShift() {} + + /** + * the class name (used to display statistics) + */ + string className() const { + return "FlowShopOpMutationShift"; + } + + /** + * modifies the parent with a shift mutation + * @param FlowShop & _genotype the parent genotype (will be modified) + */ + bool operator()(FlowShop & _genotype) { + bool isModified; + int direction; + unsigned tmp; + + // schedulings + vector initScheduling = _genotype.getScheduling(); + vector resultScheduling = initScheduling; + + // computation of the 2 random points + unsigned point1, point2; + do { + point1 = rng.random(resultScheduling.size()); + point2 = rng.random(resultScheduling.size()); + } while (point1 == point2); + + // direction + if (point1 < point2) direction = 1; + else direction = -1; + // mutation + tmp = resultScheduling[point1]; + for(unsigned i=point1 ; i!=point2 ; i+=direction) + resultScheduling[i] = resultScheduling[i+direction]; + resultScheduling[point2] = tmp; + + // update (if necessary) + if (resultScheduling != initScheduling) { + // update + _genotype.setScheduling(resultScheduling); + // the genotype has been modified + isModified = true; + } + else { + // the genotype has not been modified + isModified = false; + } + + // return 'true' if the genotype has been modified + return isModified; + } + +}; + +#endif /*FLOWSHOPOPMUTATIONSHIFT_H_*/ diff --git a/branches/paradiseo-moeo-1.0/tutorials/lesson1/Makefile.am b/branches/paradiseo-moeo-1.0/tutorials/lesson1/Makefile.am new file mode 100644 index 000000000..e398ef469 --- /dev/null +++ b/branches/paradiseo-moeo-1.0/tutorials/lesson1/Makefile.am @@ -0,0 +1,9 @@ + +noinst_PROGRAMS = FlowShopEA + +FlowShopEA_SOURCES = FlowShopEA.cpp + +LDADD = -L$(top_builddir)/src ${EO_DIR}/src/libeo.a ${EO_DIR}/src/utils/libeoutils.a + +INCLUDES = -I${EO_DIR}/src/ -I${MO_DIR}/src/ -I$(top_srcdir)/src + diff --git a/branches/paradiseo-moeo-1.0/tutorials/lesson1/make_eval_FlowShop.h b/branches/paradiseo-moeo-1.0/tutorials/lesson1/make_eval_FlowShop.h new file mode 100644 index 000000000..7545b37b8 --- /dev/null +++ b/branches/paradiseo-moeo-1.0/tutorials/lesson1/make_eval_FlowShop.h @@ -0,0 +1,55 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// make_eval_FlowShop.h +// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2007 +/* + This library... + + Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr + */ +//----------------------------------------------------------------------------- + +#ifndef MAKE_EVAL_FLOWSHOP_H_ +#define MAKE_EVAL_FLOWSHOP_H_ + + +#include +#include +#include "FlowShop.h" +#include "FlowShopBenchmarkParser.h" +#include "FlowShopEval.h" + +/* + * This function creates an eoEvalFuncCounter that can later be used to evaluate an individual. + * @param eoParser& _parser to get user parameters + * @param eoState& _state to store the memory + */ +eoEvalFuncCounter & do_make_eval(eoParser& _parser, eoState& _state) { + + // benchmark file name + string benchmarkFileName = _parser.getORcreateParam(string(), "BenchmarkFile", "Benchmark file name (benchmarks are available at " + BENCHMARKS_WEB_SITE + ")", 'B',"Representation", true).value(); + if (benchmarkFileName == "") { + std::string stmp = "*** Missing name of the benchmark file\n"; + stmp += " Type '-B=the_benchmark_file_name' or '--BenchmarkFile=the_benchmark_file_name'\n"; + stmp += " Benchmarks files are available at " + BENCHMARKS_WEB_SITE; + throw std::runtime_error(stmp.c_str()); + } + // reading of the parameters contained in the benchmark file + FlowShopBenchmarkParser fParser(benchmarkFileName); + unsigned M = fParser.getM(); + unsigned N = fParser.getN(); + std::vector< std::vector > p = fParser.getP(); + std::vector d = fParser.getD(); + + // build of the initializer (a pointer, stored in the eoState) + FlowShopEval* plainEval = new FlowShopEval(M, N, p, d); + // turn that object into an evaluation counter + eoEvalFuncCounter* eval = new eoEvalFuncCounter (* plainEval); + // store in state + _state.storeFunctor(eval); + // and return a reference + return *eval; +} + +#endif /*MAKE_EVAL_FLOWSHOP_H_*/ diff --git a/branches/paradiseo-moeo-1.0/tutorials/lesson1/make_genotype_FlowShop.h b/branches/paradiseo-moeo-1.0/tutorials/lesson1/make_genotype_FlowShop.h new file mode 100644 index 000000000..157481f36 --- /dev/null +++ b/branches/paradiseo-moeo-1.0/tutorials/lesson1/make_genotype_FlowShop.h @@ -0,0 +1,49 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// make_genotype_FlowShop.h +// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2007 +/* + This library... + + Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr + */ +//----------------------------------------------------------------------------- + +#ifndef MAKE_GENOTYPE_FLOWSHOP_H_ +#define MAKE_GENOTYPE_FLOWSHOP_H_ + +#include +#include +#include "FlowShop.h" +#include "FlowShopInit.h" +#include "FlowShopBenchmarkParser.h" + +/* + * This function creates an eoInit that can later be used to initialize the population (see make_pop.h). + * @param eoParser& _parser to get user parameters + * @param eoState& _state to store the memory + */ +eoInit & do_make_genotype(eoParser& _parser, eoState& _state) { + + // benchmark file name + string benchmarkFileName = _parser.getORcreateParam(string(), "BenchmarkFile", "Benchmark file name (benchmarks are available at " + BENCHMARKS_WEB_SITE + ")", 'B',"Representation", true).value(); + if (benchmarkFileName == "") { + std::string stmp = "*** Missing name of the benchmark file\n"; + stmp += " Type '-B=the_benchmark_file_name' or '--BenchmarkFile=the_benchmark_file_name'\n"; + stmp += " Benchmarks files are available at " + BENCHMARKS_WEB_SITE; + throw std::runtime_error(stmp.c_str()); + } + // reading of number of jobs to schedule contained in the benchmark file + FlowShopBenchmarkParser fParser(benchmarkFileName); + unsigned N = fParser.getN(); + + // build of the initializer (a pointer, stored in the eoState) + eoInit* init = new FlowShopInit(N); + // store in state + _state.storeFunctor(init); + // and return a reference + return *init; +} + +#endif /*MAKE_GENOTYPE_FLOWSHOP_H_*/ diff --git a/branches/paradiseo-moeo-1.0/tutorials/lesson1/make_op_FlowShop.h b/branches/paradiseo-moeo-1.0/tutorials/lesson1/make_op_FlowShop.h new file mode 100644 index 000000000..23c05c72d --- /dev/null +++ b/branches/paradiseo-moeo-1.0/tutorials/lesson1/make_op_FlowShop.h @@ -0,0 +1,106 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// make_op_FlowShop.h +// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2007 +/* + This library... + + Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr + */ +//----------------------------------------------------------------------------- + +#ifndef MAKE_OP_FLOWSHOP_H_ +#define MAKE_OP_FLOWSHOP_H_ + +#include +#include +#include +#include +#include +#include +#include +#include "FlowShopOpCrossoverQuad.h" +#include "FlowShopOpMutationShift.h" +#include "FlowShopOpMutationExchange.h" + +/* + * This function builds the operators that will be applied to the eoFlowShop + * @param eoParameterLoader& _parser to get user parameters + * @param eoState& _state to store the memory + */ +eoGenOp & do_make_op(eoParameterLoader& _parser, eoState& _state) { + + ///////////////////////////// + // Variation operators + //////////////////////////// + + // the crossover + //////////////// + + // a first crossover + eoQuadOp *cross = new FlowShopOpCrossoverQuad; + // store in the state + _state.storeFunctor(cross); + + // relative rate in the combination + double cross1Rate = _parser.createParam(1.0, "crossRate", "Relative rate for the only crossover", 0, "Variation Operators").value(); + // creation of the combined operator with this one + eoPropCombinedQuadOp *propXover = new eoPropCombinedQuadOp(*cross, cross1Rate); + // store in the state + _state.storeFunctor(propXover); + + + // the mutation + /////////////// + + // a first mutation : the shift mutation + eoMonOp *mut = new FlowShopOpMutationShift; + _state.storeFunctor(mut); + // its relative rate in the combination + double mut1Rate = _parser.createParam(0.5, "shiftMutRate", "Relative rate for shift mutation", 0, "Variation Operators").value(); + // creation of the combined operator with this one + eoPropCombinedMonOp *propMutation = new eoPropCombinedMonOp(*mut, mut1Rate); + _state.storeFunctor(propMutation); + + // a second mutation : the exchange mutation + mut = new FlowShopOpMutationExchange; + _state.storeFunctor(mut); + // its relative rate in the combination + double mut2Rate = _parser.createParam(0.5, "exchangeMutRate", "Relative rate for exchange mutation", 0, "Variation Operators").value(); + // addition of this one to the combined operator + propMutation -> add(*mut, mut2Rate); + + // end of crossover and mutation definitions + //////////////////////////////////////////// + + // First read the individual level parameters + eoValueParam& pCrossParam = _parser.createParam(0.25, "pCross", "Probability of Crossover", 'c', "Variation Operators" ); + // minimum check + if ( (pCrossParam.value() < 0) || (pCrossParam.value() > 1) ) + throw runtime_error("Invalid pCross"); + + eoValueParam& pMutParam = _parser.createParam(0.35, "pMut", "Probability of Mutation", 'm', "Variation Operators" ); + // minimum check + if ( (pMutParam.value() < 0) || (pMutParam.value() > 1) ) + throw runtime_error("Invalid pMut"); + + // the crossover - with probability pCross + eoProportionalOp * propOp = new eoProportionalOp ; + _state.storeFunctor(propOp); + eoQuadOp *ptQuad = new eoQuadCloneOp; + _state.storeFunctor(ptQuad); + propOp -> add(*propXover, pCrossParam.value()); // crossover, with proba pcross + propOp -> add(*ptQuad, 1-pCrossParam.value()); // nothing, with proba 1-pcross + + // now the sequential + eoSequentialOp *op = new eoSequentialOp; + _state.storeFunctor(op); + op -> add(*propOp, 1.0); // always do combined crossover + op -> add(*propMutation, pMutParam.value()); // then mutation, with proba pmut + + // return a reference + return *op; +} + +#endif /*MAKE_OP_FLOWSHOP_H_*/