模拟退火算法

前几天计算智能方法的实验作业,简单封装了一下,可以直接调用。

等有空了再完善。

class SimulateAnneal {
  private:
    double eps;
    double inf;
    int itercnt;

  public:
    SimulateAnneal() {
        eps = 1e-12;
        inf = 2e12;
        itercnt = 0;
    }
    double getEps() const { return eps; }
    double getInf() const { return inf; }
    int getItercnt() const { return itercnt; }
    void setEps(const double &_eps) { eps = _eps; }
    void setInf(const double &_inf) { inf = _inf; }

    std::function<double(double)> defaultExponentCooling =
        [](double temp) -> double { return temp * 0.998; };
    std::function<double(double)> defaultLinearCooling =
        [](double temp) -> double { return temp - 0.168; };

    std::function<double(double)> defaultInverseCooling =
        [](double temp) -> double { return temp / (0.0012 * temp + 1); };
    std::function<double(double)> defaultQuickCooling =
        [&](double temp) -> double { return temp / (getItercnt() + 1); };
    std::function<double(double)> defaultLogarithmicCooling =
        [&](double temp) -> double { return 3000.0 / (std::log1p(getItercnt()) + 1); };

    template <typename T>
    std::pair<T, std::vector<T>>
    solve(std::vector<T> &initial,
          const std::function<T(std::vector<T> &)> &calc,
          const std::function<bool(T, T)> &better,
          const std::function<std::vector<T>(std::vector<T> &, double)> &change,
          const std::function<double(double)> &CoolingSchedule,
          double temperature) {
        std::vector<T> current = initial;
        std::vector<T> ret = initial;
        T ans = calc(current);
        itercnt = 0;
        std::uniform_real_distribution<double> P(0, 1.0);
        std::random_device rd;
        std::default_random_engine engine{rd()};
        while (temperature > eps) {
            std::vector<T> now = change(current, temperature);
            T value = calc(now);
            double delta = -fabs(value - ans);
            if (better(value, ans)) {
                current = now;
                ret = now;
                ans = value;
            } else if (exp(delta / temperature) > P(engine)) {
                current = now;
            }
            temperature = CoolingSchedule(temperature);
            itercnt++;
        }
        return {ans, ret};
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值