📄 eorealop.h
字号:
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-//-----------------------------------------------------------------------------// eoRealOp.h// (c) Maarten Keijzer 2000 - Marc Schoenauer 2001/* 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Contact: Marc.Schoenauer@polytechnique.fr mak@dhi.dk *///-----------------------------------------------------------------------------#ifndef eoRealOp_h#define eoRealOp_h//-----------------------------------------------------------------------------#include <algorithm> // swap_ranges#include <utils/eoRNG.h>#include <es/eoReal.h>#include <utils/eoRealVectorBounds.h>//-----------------------------------------------------------------------------/** eoUniformMutation --> changes all values of the std::vector by uniform choice with range epsilon with probability p_change per variable\class eoUniformMutation eoRealOp.h Tutorial/eoRealOp.h\ingroup parameteric*/template<class EOT> class eoUniformMutation: public eoMonOp<EOT>{ public: /** * Constructor without bounds == unbounded variables :-) * not very clean, but who's doing unbounded optimization anyway? * and it's there mostly for backward compatibility * * @param _epsilon the range for uniform nutation * @param _p_change the probability to change a given coordinate */ eoUniformMutation(const double& _epsilon, const double& _p_change = 1.0): homogeneous(true), bounds(eoDummyVectorNoBounds), epsilon(1, _epsilon), p_change(1, _p_change) {} /** * Constructor with bounds * @param _bounds an eoRealVectorBounds that contains the bounds * @param _epsilon the range for uniform mutation - a double to be scaled * @param _p_change the one probability to change all coordinates */ eoUniformMutation(eoRealVectorBounds & _bounds, const double& _epsilon, const double& _p_change = 1.0): homogeneous(false), bounds(_bounds), epsilon(_bounds.size(), _epsilon), p_change(_bounds.size(), _p_change) { // scale to the range - if any for (unsigned i=0; i<bounds.size(); i++) if (bounds.isBounded(i)) epsilon[i] *= _epsilon*bounds.range(i); } /** * Constructor with bounds * @param _bounds an eoRealVectorBounds that contains the bounds * @param _epsilon the VECTOR of ranges for uniform mutation * @param _p_change the VECTOR of probabilities for each coordinates */ eoUniformMutation(eoRealVectorBounds & _bounds, const std::vector<double>& _epsilon, const std::vector<double>& _p_change): homogeneous(false), bounds(_bounds), epsilon(_epsilon), p_change(_p_change) {} /// The class name. virtual std::string className() const { return "eoUniformMutation"; } /** * Do it! * @param _eo The indi undergoing the mutation */ bool operator()(EOT& _eo) { bool hasChanged=false; if (homogeneous) // implies no bounds object for (unsigned lieu=0; lieu<_eo.size(); lieu++) { if (rng.flip(p_change[0])) { _eo[lieu] += 2*epsilon[0]*rng.uniform()-epsilon[0]; hasChanged = true; } } else { // sanity check ? if (_eo.size() != bounds.size()) throw std::runtime_error("Invalid size of indi in eoUniformMutation"); for (unsigned lieu=0; lieu<_eo.size(); lieu++) if (rng.flip(p_change[lieu])) { // check the bounds double emin = _eo[lieu]-epsilon[lieu]; double emax = _eo[lieu]+epsilon[lieu]; if (bounds.isMinBounded(lieu)) emin = std::max(bounds.minimum(lieu), emin); if (bounds.isMaxBounded(lieu)) emax = std::min(bounds.maximum(lieu), emax); _eo[lieu] = emin + (emax-emin)*rng.uniform(); hasChanged = true; } } return hasChanged; }private: bool homogeneous; // == no bounds passed in the ctor eoRealVectorBounds & bounds; std::vector<double> epsilon; // the ranges for mutation std::vector<double> p_change; // the proba that each variable is modified};/** eoDetUniformMutation --> changes exactly k values of the std::vector by uniform choice with range epsilon\class eoDetUniformMutation eoRealOp.h Tutorial/eoRealOp.h\ingroup parameteric*/template<class EOT> class eoDetUniformMutation: public eoMonOp<EOT>{ public: /** * (Default) Constructor for homogeneous genotype * it's there mostly for backward compatibility * * @param _epsilon the range for uniform nutation * @param number of coordinate to modify */ eoDetUniformMutation(const double& _epsilon, const unsigned& _no = 1): homogeneous(true), bounds(eoDummyVectorNoBounds), epsilon(1, _epsilon), no(_no) {} /** * Constructor with bounds * @param _bounds an eoRealVectorBounds that contains the bounds * @param _epsilon the range for uniform nutation (to be scaled if necessary) * @param number of coordinate to modify */ eoDetUniformMutation(eoRealVectorBounds & _bounds, const double& _epsilon, const unsigned& _no = 1): homogeneous(false), bounds(_bounds), epsilon(_bounds.size(), _epsilon), no(_no) { // scale to the range - if any for (unsigned i=0; i<bounds.size(); i++) if (bounds.isBounded(i)) epsilon[i] *= _epsilon*bounds.range(i); } /** * Constructor with bounds and full std::vector of epsilon * @param _bounds an eoRealVectorBounds that contains the bounds * @param _epsilon the VECTOR of ranges for uniform mutation * @param number of coordinate to modify */ eoDetUniformMutation(eoRealVectorBounds & _bounds, const std::vector<double>& _epsilon, const unsigned& _no = 1): homogeneous(false), bounds(_bounds), epsilon(_epsilon), no(_no) { // scale to the range - if any for (unsigned i=0; i<bounds.size(); i++) if (bounds.isBounded(i)) epsilon[i] *= _epsilon[i]*bounds.range(i); } /// The class name. virtual std::string className() const { return "eoDetUniformMutation"; } /** * Do it! * @param _eo The indi undergoing the mutation */ bool operator()(EOT& _eo) { if (homogeneous) for (unsigned i=0; i<no; i++) { unsigned lieu = rng.random(_eo.size()); // actually, we should test that we don't re-modify same variable! _eo[lieu] = 2*epsilon[0]*rng.uniform()-epsilon[0]; } else { // sanity check ? if (_eo.size() != bounds.size()) throw std::runtime_error("Invalid size of indi in eoDetUniformMutation"); for (unsigned i=0; i<no; i++) { unsigned lieu = rng.random(_eo.size()); // actually, we should test that we don't re-modify same variable! // check the bounds double emin = _eo[lieu]-epsilon[lieu]; double emax = _eo[lieu]+epsilon[lieu]; if (bounds.isMinBounded(lieu)) emin = std::max(bounds.minimum(lieu), emin); if (bounds.isMaxBounded(lieu)) emax = std::min(bounds.maximum(lieu), emax); _eo[lieu] = emin + (emax-emin)*rng.uniform(); } } return true; }private: bool homogeneous; // == no bounds passed in the ctor eoRealVectorBounds & bounds; std::vector<double> epsilon; // the ranges of mutation unsigned no;};// two arithmetical crossovers/** eoSegmentCrossover --> uniform choice in segment == arithmetical with same value along all coordinates\class eoSegmentCrossover eoRealOp.h Tutorial/eoRealOp.h\ingroup parameteric*/template<class EOT> class eoSegmentCrossover: public eoQuadOp<EOT>{ public: /** * (Default) Constructor. * The bounds are initialized with the global object that says: no bounds. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -