模擬退火演算法(初步)
阿新 • • 發佈:2019-02-06
關於模擬退火演算法的介紹在知乎,CSDN都有很多前輩給出了自己的介紹,我認為都講得很好。其實模擬退火演算法應用於一維搜尋的話,以概率為1收斂於最優,而且早熟收斂發生的概率很低。和粒子群相比,收斂速度慢,依賴於降溫的速度,但是粒子群實在是太容易收斂到區域性最優了,而且一旦到了區域性最優就跳不出來了,因為粒子群演算法是沒有變異的。
綜合下來,我覺得遺傳演算法和模擬退火演算法都比較優秀,在一維搜尋的表現都比較好。當然,每種演算法都有存在的價值,這幾種演算法我現在都只應用在了一維搜尋上。我一開始瞭解這些演算法的目的是為了求六自由度平臺的正解問題,之後如果我真的寫了,再去考慮吧。畢竟是一個六輸入六輸出,我要考慮一波怎麼去寫。
下面給出模擬退火演算法的C++程式碼:
//模擬退火演算法 #include "iostream" #include "algorithm" #include "vector" #include "random" #include "iterator" #include "cmath" #define MAX_COUNT 50000 using namespace std; double fitness_function(double x)//求此函式的最大值 { //return x*x*sin(3 * x)*cos(2 * x); //return -x*(x - 1);//適應函式 return x + 10 * sin(5 * x) + 7 * cos(4 * x); } class Anneal { public: Anneal() = default; Anneal(const Anneal& a) { temp = a.temp; rate = a.rate; pre = a.pre; cur = a.cur; } ~Anneal() {}; double temp = 200; double rate = 0.98; double pre; double cur; }; int main() { static uniform_real_distribution<double> u(0, 1);//隨機數生成範圍 static default_random_engine e;//隨機數生成引擎 static uniform_real_distribution<double> uu(-10, 10);//隨機數生成範圍 static default_random_engine ee;//隨機數生成引擎 Anneal a; a.pre = fitness_function(uu(ee)); for (int i = 0; i < MAX_COUNT; i++) { a.cur = fitness_function(uu(ee)); if (a.cur >= a.pre) a.pre = a.cur; else { double delta = a.cur - a.pre;//注意這是負數 if (u(e) < exp(delta/a.temp))//指數為負,因此一定在0到1間變化 a.pre = a.cur; } a.temp *= a.rate; cout << a.pre << endl; } while (1); return 0; }