/* The Evolving Distribution Objects framework (EDO) is a template-based, ANSI-C++ evolutionary computation library which helps you to write your own estimation of distribution algorithms. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Copyright (C) 2011 Thales group */ /* Authors: Johann Dréo Pierre Savéant */ #ifndef _edoRepairerDispatcher_h #define _edoRepairerDispatcher_h #include #include #include "edoRepairer.h" /** Repair a candidate solution by sequentially applying several repairers on * subparts of the solution (subparts being defined by the corresponding set * of indexes). * * Only work on EOT that implements the "push_back( EOT::AtomType )" and * "operator[](uint)" and "at(uint)" methods (i.e. random access containers). * * Expects _addresses_ of the repairer operators. * * Use the second template type if you want a different container to store * indexes. You can use any iterable. For example, you may want to use a set if * you need to be sure that indexes are use only once: * edoRepairerDispatcher > rpd; * std::set idx(1,1); * idx.insert(2); * rpd.add( idx, &repairer ); * * @example t-dispatcher-round.cpp * * @ingroup Repairers */ template < typename EOT, typename ICT = std::vector > class edoRepairerDispatcher : public edoRepairer, std::vector< std::pair< ICT, edoRepairer< EOT >* > > { public: //! Empty constructor edoRepairerDispatcher() : std::vector< std::pair< std::vector< unsigned int >, edoRepairer< EOT >* > >() {} //! Constructor with a single index set and repairer operator edoRepairerDispatcher( ICT idx, edoRepairer* op ) : std::vector< std::pair< std::vector< unsigned int >, edoRepairer< EOT >* > >() { this->add( idx, op ); } //! Add more indexes set and their corresponding repairer operator address to the list void add( ICT idx, edoRepairer* op ) { assert( idx.size() > 0 ); assert( op != NULL ); this->push_back( std::make_pair(idx, op) ); } //! Repair a solution by calling several repair operator on subset of indexes virtual void operator()( EOT& sol ) { // std::cout << "in dispatcher, sol = " << sol << std::endl; // ipair is an iterator that points on a pair of for( typename edoRepairerDispatcher::iterator ipair = this->begin(); ipair != this->end(); ++ipair ) { assert( ipair->first.size() <= sol.size() ); // assert there is less indexes than items in the whole solution // a partial copy of the sol EOT partsol; // std::cout << "\tusing indexes = "; // j is an iterator that points on an uint for( std::vector< unsigned int >::iterator j = ipair->first.begin(); j != ipair->first.end(); ++j ) { // std::cout << *j << " "; // std::cout.flush(); partsol.push_back( sol.at(*j) ); } // for j // std::cout << std::endl; // std::cout << "\tpartial sol = " << partsol << std::endl; assert( partsol.size() > 0 ); // apply the repairer on the partial copy // the repairer is a functor, thus second is callable (*(ipair->second))( partsol ); { // copy back the repaired partial solution to sol // browse partsol with uint k, and the idx set with an iterator (std::vector is an associative tab) unsigned int k=0; for( std::vector< unsigned int >::iterator j = ipair->first.begin(); j != ipair->first.end(); ++j ) { sol[ *j ] = partsol[ k ]; k++; } // for j } // context for k } // for ipair } }; #endif // !_edoRepairerDispatcher_h