奇妙的退火

2021-07-15 06:12:23 字數 1781 閱讀 9414

退火演算法大致意義上就是在貪心的基礎上加入隨機量,以一定的概率來接受乙個比當前解要差的解,使其有機會跳出乙個區域性的最優解,達到全域性的最優解。

之所以叫做退火演算法就是在這個概率的計算上參考了金屬冶煉的退火過程。p(de) = exp( de/(kt) )

公式。k是乙個常數,exp表示自然指數,且de<0,隨著溫度的降低,機率隨之降低。

tsp挺常見到用這個的,典型的就是旅行商問題,不過作為乙個過程簡單,通用,魯棒性強,適用於並行處理非線性優化問題的演算法,退火演算法在其他的地方在其它地方使用時,退火演算法的時間問題經常很難處理。

因為退火演算法的特性決定(1)如果降溫過程越緩慢,得到的解就會越優化,與此相對的是減慢收斂速度;

(2)而如果降溫過程過快,又難以得到全域性最優解。

在經典退火演算法上的優化方式倒是不少,例如(1)增加記憶功能。(2)在程序的適當時機增加公升溫過程。(3) 額外做乙個補充搜尋過程(4)以多次搜尋策略代替標準的sa的單次比較等。但仍然要在退火平衡條件上來回權衡,因為決大多數時候在同一題目裡不同組資料的資料量也有著巨大的差距。很多時候強行使全部資料都能在1000毫秒內跑完都會犧牲精度,不強求跑完大資料直接就過不了。

試著採用過加入乙個計時函式強行卡著時間限制終止運算輸出結果,但實際使用上具體時間點很難拿捏。就以最簡單的乙個01揹包問題為例。

#include #include #include #include #define t0 1000

#define tf 0.01

#define t 0.8

#define n 1000

#define m 50

int weight[m],profit[m],contain;

int premaxp = 0, bestmaxp = 0;

int a[m] = , preseq[m] = , bestseq[m]=;

int calprofit(int a[m])

int calweight(int a[m])

return w;

}void initialize(void)

premaxp = calprofit(a);

bestmaxp = premaxp;

}void getrand(int *i, int *j) }

void change(void)

if (calweight(a) > contain)

}void sa(void)

premaxp = calprofit(a);

bestmaxp = premaxp;

}else

premaxp = calprofit(a);

}else

premaxp = calprofit(a);

}else}}

}}

t = t * t;

}

}

int main(void)

srand((unsigned)time(null));

initialize();

sa();

printf("%d\n", bestmaxp);

return 1;

}

我沒做優化但就以乙個(揹包容量,m<=200)和n(物品數量,n<=30)這樣的資料量居然是過不完的,多測幾次上下也有個波動。雖然這裡面肯定有很大一部分程式寫的太蠢的原因但也可以體現一下退火演算法拿來做題時的侷限。

何況有的比賽記得是禁用隨機函式的,山窮水盡的時候寫乙個還是比寫個運氣好才能得10分的沒有演算法的演算法強的。

生命的奇妙!

生命只有一次,而且轉瞬即逝。今年已經二十二歲了,差不多也已經度過了生命的三分之一,或者更多.二十多年過去了,應該對這二十年做乙個總結 前十年我覺得是快樂的度過的,我想應該不是我乙個人這麼認為。沒有為買房擔心,沒有為找不到工作而著急.初中那三年我認為也是非常的快樂,純真質樸。你笑表明了你很快樂,眉頭緊...

奇妙的數字

小明發現乙個奇秒的數字,他的平方和立方正好把0到 9 的所有數字只用了一遍,你能猜出這個數字是多少嗎?請填寫 該數字,不要填寫任何多餘的內用 include include include include using namespace std int fun int i int len char ...

奇妙的語言

初識c語言 第一次接觸這門新的課程,可能大多數人接觸到的第乙個程式都是 對於我來說第乙個 是這個 不過,因人而異嘛 int main 簡簡單單的幾行 便可以編譯出 hello world 這樣一句話來,想想都感覺神奇更別說是親手試試了。開始的我十分好奇這到底是為什麼,電腦是如何識別出來並開始編譯出來...