1. 程式人生 > >模擬退火的一些個人見解

模擬退火的一些個人見解

首先通過下面這個連結大概瞭解了一下什麼是模擬退火,我覺得這篇部落格還是不錯的,但是最開始看完還是感覺很迷茫,不知道模擬退火改如何去應用並解決問題。

為什麼叫模擬退火呢?

想象一個高溫物體的降溫過程。其溫度為T時出現能量差為dE的降溫概率為P(dE) =  e ^ ( -dE / (k * T) ) 。

其實就是溫度越高降溫的概率越大,溫度越低降溫概率越小。而模擬退火就是利用這樣一種思想去進行搜尋。

那麼在進行搜尋的時候首先定義一個初始值( 溫度 ) T , 一個係數 r ( 降溫速度  0 < r < 1 ) , 假設你當前狀態為 f i , 你的下一個狀態為 f i +1 , 對這兩個狀態進行評價,如果更接近你想要的結果,就更新到這個狀態,否則則以 P ( dE ) 的概率去更新到 這個狀態,但是其實在實際題目中,這個概率是不必要的,這一步有時是可以忽略掉的。我們可以想象,隨著搜尋次數的不斷增多,搜尋範圍將越來越趨近於穩定,也就是隨著時間的增長溫度降低的概率越來越低,直到趨近於1。對應搜尋就是隨著你搜索的次數越多,你搜索到的值是你想要的值的概率就越大。找了一張圖可以直觀的感受一下模擬退火的過程。

所以具體步驟

1.  初始溫度 T , 精度 EPS ( 溫度的下界 ) ,當T < EPS 時結束搜尋,輸出當前最優解

2.  在這個狀態周圍搜尋出一個新的狀態 , 如果是當前最優解則更新 ,如果不是則以降溫概率更新 ( 可忽略 )

3.  縮小T.

對於初始溫度T設定,初始值與你的搜尋範圍有關。因為T也決定你的搜尋範圍,為什麼不是最優解以降溫概率更新的部分可以忽略我是這樣認為的,我覺得初始的搜尋範圍可以取整個搜尋範圍的大小,任意一個初始搜尋點,每次搜尋當前搜尋範圍內的狀態,進行最優解的更新以及縮小搜尋範圍,根據模擬退火的思想,隨著搜尋範圍 T ( 溫度 )

的降低,最優解會越來越穩定,而我個人認為的取搜尋範圍,然後通過係數去減小搜尋範圍,這樣就可以貪心的去保留當前最優解,最終依舊大概率獲得全域性最優解。可以忽略降溫概率更新是因為依舊可以通過搜尋範圍的變化去得到一個更優值。最終當搜尋範圍小於你要求的精度時,輸出當前最優解。

通過別人的一點認識(點選開啟連結),對於精度要求為小數點後1位的,下界可以取1e-3或1e-4,降溫係數取 0.8 ,對於精度要求為1e-5 , 下界可取1e-7或1e-8 ,降溫係數取 0.98。 可以說是取精度要求* 1e-2 或 1e-3 為下界?然後降溫係數在具體除錯這樣?而且根據實際情況降溫係數取0.98或0.99的速度也還可以,這個我在下面的題目進行了小實驗。

一.  一維座標搜尋

以hdu 2899為例

題意

F(x) = 6 * x^7+8*x^6+7*x^3+5*x^2-y*x (0 <= x <=100)

F (x) 的最小值

我們可訂初始溫度 T 為 100 ,降溫係數取 0.98 ,溫度下界 ( 精度 )取1e-6 , 搜尋起始點任意,取( 0 , 0 ) 。

題目很簡單我就直接貼程式碼了。

#include<bits/stdc++.h>
using namespace std;
const double EPS=1e-6;
const double r=0.98;
const int dx[2]={-1,1};
double y;

double F(double x)
{
    return 6*pow(x,7)+8*pow(x,6)+7*pow(x,3)+5*pow(x,2)-y*x;
}

int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        cin>>y;
        double step=100;
        double x=0;
        while(step>EPS)
        {
            for(int i=0;i<2;i++)
            {
                double next_x=x+dx[i]*step;
                if(next_x<0||next_x>100)
                    continue;
                if(F(next_x)<F(x))
                    x=next_x;
            }
            step*=r;
        }
        printf("%.4f\n",F(x));
    }
    return 0;
}


通過在hdu的提交,初始溫度100,下界1e-6 , 退火速率 0.99時140ms,0.98時為78ms。

二. 二維座標搜尋

以hdu 3932 為例

題意:

給你一個搜尋範圍 ( 0,0 ) 到 ( X ,Y )這個矩形範圍,給你 N 個點 , 要求找出一個點使這個點到這 N 個點的最大距離最小。

可以想象的就是把一維轉變成二維,那麼單點搜尋我們就可以變成隨機多點並行搜尋,原來的雙向移動,轉變為360度隨機移動。最後在多點的搜尋結果中取最優。

顯然移動是以圓的範圍移動的,那麼溫度上界 T 取矩形對角線, 即圓的最大半徑,精度為小數點後1位, 精確度EPS取1e-3, 降溫速率 r 取0.8,對於每個點我隨機了36次移動,具體這個值怎麼取更合適我還沒考慮清楚。程式碼如下。

#include<bits/stdc++.h>
using namespace std;

const double EPS=1e-3;
const double PI=acos(-1.0);
const double INF=0x3f3f3f3f;
const double r=0.8;
const int maxn=1e4+5;
const int num=20;

struct Point{
    double x,y;
};

Point a[maxn];
Point m[maxn];
int n;
double d[maxn];

double dist(Point A, Point B)
{
    return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}

double MAX(Point t)
{
    double res=-1;
    for(int i=0;i<n;i++)
        res=max(res,dist(t,a[i]));
    return res;
}

int main()
{
    double xx,yy;
    srand(time(0));
    while(cin>>xx>>yy>>n)
    {
        for(int i=0;i<n;i++)
            cin>>a[i].x>>a[i].y;
        for(int i=0;i<num;i++)
        {
            m[i].x=(rand()%1000+1)/1000.0*xx;
            m[i].y=(rand()%1000+1)/1000.0*yy;
            d[i]=MAX(m[i]);
        }
        double T=sqrt(xx*xx+yy*yy);
        Point next,now;
        while(T>EPS)
        {
            for(int i=0;i<num; i++)
            {
                now.x=m[i].x;
                now.y=m[i].y;
                for(int j=0;j<36;j++)
                {
                    double ang=(rand()%1000+1)/1000.0*2*PI;
                    next.x=now.x+cos(ang)*T;
                    next.y=now.y+sin(ang)*T;
                    if(next.x<0||next.x>xx||next.y<0||next.y>yy)
                        continue;
                    if(MAX(next)<d[i])
                    {
                        m[i].x=next.x;
                        m[i].y=next.y;
                        d[i]=MAX(next);
                    }
                }
            }
            T*=r;
        }
        int res;
        double ans=INF;
        for(int i=0;i<num;i++)
        {
            if(d[i]<ans)
            {
                ans=d[i];
                res=i;
            }
        }
        printf("(%.1f,%.1f).\n",m[res].x,m[res].y);
        printf("%.1f\n",ans);
    }
    return 0;
}


三. 近似解決旅行商問題

留坑。。。

哪裡有錯誤請指出!謝謝!

相關推薦

模擬退火一些個人見解

首先通過下面這個連結大概瞭解了一下什麼是模擬退火,我覺得這篇部落格還是不錯的,但是最開始看完還是感覺很迷茫,不知道模擬退火改如何去應用並解決問題。 為什麼叫模擬退火呢? 想象一個高溫物體的降溫過程。其溫度為T時出現能量差為dE的降溫概率為P(dE) =  e ^ ( -d

Oracle關於資料庫鎖處理的一些個人見解

/*使用者鎖,資料庫的鎖有的時候是比較耗費資源的,特別是發生鎖等待的時候,我們必須找到發生等待的鎖,有可能的話,殺掉該程序。 這個語句將查詢到資料庫中所有的DML語句產生的鎖,還可以發現,任何DML語句其實產生了兩個鎖,一個是表鎖,一個是行鎖。 可以通過alter syste

開發中關於RunLoop和RunTime一些個人見解

RunLoop: 1.       實際上 RunLoop 就是一個函式,其內部是一個 do-while 迴圈。當你呼叫 CFRunLoopRun() 時,執行緒就會一直停留在這個迴圈裡;直到超時或被手動停止,該函式才會返回。 2.       作用:通過 RunLo

ab壓測工具的一些個人見解

ab壓測工具(linux版)由於網上教程一大把,今天也按照教程好好研究了一番,下面寫一下對此工具的一些個人見解,如有不妥,希望一起探討。 優點: 1、小巧。 2、理論支援655350併發數。實際32環境中使用,超過10000就跑不下去,更改配置後還是如此。經試驗32測試環境中支援的最高併

針對php面試題中的問題的一些個人見解

翻了翻網上的php面試題,看到了一些問題,提出了個人的一些見解! 氣泡排序的優化! 看網上的php面試題有氣泡排序,細察之下發現可以優化。 原始碼: <?php function so

對於剛工作不久的畢業生想換工作的一些個人見解

      我是2018年7月份畢業軟體技術專業,大學學的是Android開發,但由於16年開始工作就不好找,找的第一份工作是做軟體實施。2017年9月初,我辭掉了工作,從零開始,在家自學了一個月的java開發,10月份開始找工作,10月底找到工作,但是不是java開發,只不

評判一篇技術部落格價值的標準一些個人見解

    1.將複雜的問題簡單化:               勤勞的牛人: 把原本複雜的問題,簡單化,可以得到更多的觀眾關注度,因為只有越簡單的方式解釋越複雜的問題,才能有更多的讀者來去讀且讀懂,如果很多關鍵性問題的研究一筆帶過,且認為顯而易見,那麼說明該論文或者程式解釋得

關於還有一些公司問重寫與過載的區別個人見解

首先我認為這回暴露公司或者問你此問題人的水準 先說方法重寫和方法過載在英文中的區別分別是override和overload; 兩者比較沒有太大的意思,我們分別分析一下兩者的定義 方法重寫:子類包含於父類同名方法的現象稱為方法重寫(也被稱為方法覆蓋),需要遵循“兩同兩小一大”的規則 1.兩同:方法名相同

關於還有一些公司問重寫與重載的區別個人見解

覆蓋 意思 等於 子類 應該 發生 font 重寫 方法重載 首先我認為這回暴露公司或者問你此問題人的水準 先說方法重寫和方法重載在英文中的區別分別是override和overload; 兩者比較沒有太大的意思,我們分別分析一下兩者的定義 方法重寫:子類包含於父類同名方法的

position的relative 和 absolute 的區別個人見解

images .cn posit src ati absolut ima ive 分享    position:relative是相對原來的位置相對移動,absolute 是相對於父元素的位子移動,這裏面我個人對position:relative不是很熟悉所以只是截了這個圖

關於web程序快速開發個人見解以及經歷

fine read tab message mapper 輸出 http ble ... 由於在之前公司業務的發展,需要在基於核心業務的基礎上開發其他較為獨立的業務系統,所以就有了這個基於Dapper,DDD概念的基礎框架,由於個人基於這個框架已經經歷過兩個系統的開發,也因

模擬退火 (poj 2420, poj 2069)

mes 全局 poj include using div tracking out amp 模擬退火基本知識 其偽代碼例如以下: Let s = s0 For k = 0 through k_max (exclusive): T := temperature(k /

爬山算法和模擬退火算法簡介

出了 搜索算法 旅行 www cnblogs 所有 發的 圖1 貪心 轉自:http://www.cnblogs.com/chaosimple/archive/2013/06/10/3130664.html 一. 爬山算法 ( Hill Climbing )

node.js的一些個人感想

.post str 做的 nod parse creates () res 連接 作為一個初學者而言 node.js是一門很強大的後端語言 和PHP相比的話個人感覺node要更加直觀一些 node.js因為有很多的組件支持讓其運用起來更加簡單和快捷 對於現在這個時間就是金錢

【BZOJ3680】吊打XXX 模擬退火

esc 題解 ret 爬山 能量 truct style namespace ngx 【BZOJ3680】吊打XXX Description gty又虐了一場比賽,被虐的蒟蒻們決定吊打gty。gty見大勢不好機智的分出了n個分身,但還是被人多勢眾的蒟蒻抓住了。蒟蒻們

關於Session和cookie個人見解

是否 第一次 != redirect use p s cookie 超過 讀取 背景:因為HTTP是無狀態的協議,這樣我們無法推斷同一個用戶多次請求時記錄用戶的信息從而須要頻繁的身份校驗,包含開啟多個瀏覽器瀏覽同一個站點依然須要不停的都身份驗證。這樣就產生了sess

【BZOJ1844/2210】Pku1379 Run Away 模擬退火

tro pku str sqrt mes tchar 矩形 ron run 【BZOJ1844/2210】Pku1379 Run Away 題意:矩形區域中有一堆點,求矩形中一個位置使得它到所有點的距離的最小值最大。 題解:模擬退火的裸題,再調調調調調參就行了~

【BZOJ1038】【ZJOI2008】瞭望塔 [模擬退火]

輪廓 abs none i++ += edi bzoj1038 put continue 瞭望塔 Time Limit: 10 Sec Memory Limit: 162 MB[Submit][Status][Discuss] Description   致

sublime text 3 為配置Python開發環境所做的一些個人設置

ctrl+alt 開發 clas 1.3 pre asc tools tps 註意 我們都知道,ST3(Sublime Text 3)自帶的build python可以直接運行.py文件,但是若涉及input()函數需要輸入時,就不能用這個了。 下面是我個人所作的一些對我來

bzoj3680: 吊打XXX(模擬退火

exp span long long 接下來 main mage 要求 概率 spa   題目要求      最小(dis表示繩結到點i的距離),就是個廣義費馬點的題,模擬退火裸題QAQ   模擬退火就是優化後的爬山算法,一開始先隨機一個平均點,接下來如果隨機到的點比