1. 程式人生 > >[蒟蒻實驗室]Ep.1背包退火!

[蒟蒻實驗室]Ep.1背包退火!

max arch else archive false warn 當前 ans html

[蒟蒻實驗室]Ep.1背包退火!

· FBI Warning

· 新算法:背包退火!

· 本文所包含的思路來自於NCC79601巨佬的啟迪Orz

·算法剖析

簡單來講,背包退火就是用模擬退火的思路解決某些類型的背包問題,繼承了模擬退火的玄學復雜度,也繼承了它的不穩定性,所以能夠有效地解決大背包問題的TLE問題。這個算法能夠把數十行的代碼優化部分轉移為 洗把臉 調參的問題。

例題 :LuoGuP1049【裝箱問題】

有一個箱子容量為V,同時有n個物品,每個物品有一個體積vi。要求n個物品中,任取若幹個裝入箱內,使箱子的剩余空間為最小。

·算法過程

首先就是模擬退火的隨機設置自然就是把隨機數種子設置好,別忘了先洗臉
,然後通過模擬退火原理設置好轉移概率表達式:

1 bool accept(int del)
2 {
3     return ((del>0)||exp(-del/T) > (double)rand()/RAND_MAX);
4 } //轉移概率表達式

然鵝蒟蒻的我很難解釋清楚為什麽隨著T的減小他接受更劣解的概率會越來越小,只知道利用這個概率是e^(-dE/kT)。

使用這個概率從而達到剛開始退火,跳出當前最優解的概率大,而當靠近答案時跳出正確答案的可能性又逐漸減小。如有不懂請挪步模擬退火詳解

·偏移過程

這就是上述問題的用武之地了:以一定的概率不選當前最優解中的那個物品,從而衍生出另一種方案,如果比剛剛的更好,那麽說明運氣很好,跳到了一個更優解範圍附近

 1 if(accept(dE)) 
 2         {//以上述概率發生轉移
 3             if(vis[a])
 4             {
 5                 vis[a] = false;
 6                 tot -= v[a];
 7             }//在當前物品已選的情況下放棄選用當前物品
 8             else
 9             {
10                 if(tot + v[a] > V)
11                 {
12                     continue
; 13 } 14 vis[a] = true; 15 tot += v[a]; 16 }//在當前物品未選的情況下嘗試選用當前物品 17 }

·退火步驟

while(T > 1e-14) {
        ans=max(ans,tot); //維護最優答案,以防非酋情況發生
        a = rd; //進行隨機
        int dE = v[a];
        if(vis[a])
        {
            dE *= -1; //產生能量差
        }
        if(accept(dE)) 
        {//發生轉移
            if(vis[a])
            {
                vis[a] = false;
                tot -= v[a];
            }
            else
            {
                if(tot + v[a] > V)
                {
                    continue;
                }
                vis[a] = true;
                tot += v[a];
            }
        }
        T *= delta; //降溫
    }

該過程通過降溫系數delta對初溫為T的物體降溫,直到物體溫度冷卻接近0。但是不能直接將tot作為答案輸出,否則沒洗臉的話可能會出現跳到了較劣解的情況。

退火的一些小技巧

1. 降溫系數用0.99789(玄學參數)

2. 初溫設置為1926(玄學參數)

3. 退火的轉移概率計算式:e^(-dE/kT)

(del>0)||exp(-del/T) > (double)rand()/RAND_MAX

4.最低溫不要調的太低,不然妥妥的TLE

5.交一次不行說明rp不夠你的時間不好,原代碼再交一次也許 就行了呢

6.別忘了洗臉rp++

番外篇:論歐皇的養成

iewqufhiwefdiweduiqwediuqedwedjewui

(被某個非酋網友摁在鍵盤上打/笑哭)

技術分享圖片

這是某個沒洗臉的基佬的↑

這是我的↓

技術分享圖片

溜了溜了……

[蒟蒻實驗室]Ep.1背包退火!