演算法選擇問題
① 每天一個知識點:分治演算法:選擇問題
選擇問題的要求是找出含有 N 個元素的表 S 中的第 k 個最小的元素。
基本的演算法是簡單的遞歸策略。設 N 大於截止點(cutoff point),在截止點後元素將進行簡單的排序,v 是選出的一個元素,叫做樞紐元(pivot)。其餘的元素被放在兩個集合 和 中。 含有那些不大於 v 的元素,而 則包含那些不小於 v 的元素。
為了得到一個線性演算法,必須保證子問題只是原問題的一部分,而不僅僅只是比原問題少幾個元素。這里要解決問題就是如何花費更少的時間來尋找樞紐元。
為得到一個好的最壞情形,關鍵想法是再用一個間接層。不是從隨機元素的樣本中找出中項,而是從中項的樣本中找出中項。
基本的樞紐元選擇演算法如下:
上面給出的樞紐元選擇法,有一個專業的術語,叫做「五分化中項的中項」。「五分化中項的中項」保證每個遞歸子問題的大小最多是原問題的大約 70%。對於整個選擇演算法,樞紐元可以足夠快的算出,以確保 的運行時間。
定理:使用「五分化中項的中項」的快速選擇演算法的運行時間為 。
分治演算法還可以用來降低演算法預計所需要的比較次數。
設有 N 個數的集合 S 並且要尋找其中第 k 個最小的數 X。我們選擇 S 的子集 S『,令 δ 是某個數,使得計算過程所用的平均比較次數最小化。
找出 S』 中第 ( ) 個和第 個最小的元素,幾乎可以肯定 S 中的第 k 個元素將落在 和 之間,此時,問題變成了 2δ 個元素的選擇問題。
經過分析,會發現,若 和 ,則期望的比較次數為 ,除低次項外它是最優的。(如果 k>N/2,那麼我們可以考慮查找第(N-k)個最大元素的對稱問題。)
最後一項代表進行兩次選擇以確定 和 的代價。假設採用合理聰明的策略,則劃分的平均代價等於 N 加上 在 S 中的期望階(expected rank),即 。如果第 k 個元素在 S『 中出現,那麼代價就是 O(N)。然而,s 和 δ 已經被選取以保證這種情況以非常低的概率 o(1/N) 發生,因此該可能性的期望代價是 o(1),當它的 N 越來越大時趨向於 0。
這個分析指出,找出中項平均大約需要 1.5N 次比較。當然,該演算法為計算 s 需要浮點運算,這在一些機器上可能使該演算法減慢速度。不過即使是這樣,若能正確實現,則該演算法完全能夠比得上快速選擇實現方法。
② 遺傳演算法中選擇運算元的問題
首先介紹sort函數用法:
[B,I]=sort(A,.....),I為返回的排序後元素在原數組中的行位置或列位置.B一般為排序後的數組。舉例:
A = 3 4 2
1 5 3
4 7 1
[B,I]=sort(A)
B = 1 4 1
3 5 2
4 7 3
I = 2 1 3
1 2 1
3 3 2
[Oderfi,Indexfi]=sort(fi),因此這句話中的Oderfi保存了從小到大排列的結果,而Indexfi保存了Oderfi中對應原始數組(fi)的的原始位置。
fi_Size=(Oderfi/fi_sum)*Size 這句話挺難理解的,不過我運行了這個程序後,還是被我發現了
其中Oderf為 適應值 由小到大排列,fi_sum為適應值的總和,Size為總的個數,而fi_sum/size就是平均值,因此。fi_size中所存放的數據是Oderf中數值除以其平均值後的結果。其中必有大於1的,小於1的。我們這里的淘汰規則是淘汰掉 種群中小於平均值的數據,下邊的代碼是對這個規則的具體化
fi_S只包含0和1,其中0是小於平均值的個體,1是大於平均值的個體。
for j=1:1:fi_S(i) %Select and Reproce
TempE(kk,:)=E(Indexfi(i),:);
kk=kk+1; %kk is used to reproce
end
E中保存的是初始種群,我們每一代種群中都會有80個個體(每一行是一個個體,列數決定了個體范圍和精度),當fi_S中某個個體(記為個體A)不是0的時候,就執行了TempE(kk,:)=E(Indexfi(i),:);
這句代碼,Indexfi保存了個體A在E中的行數(也就是fi的列數),我們認定這一行(這個個體A)具有優良基因,因此保存在TempE中,進化到下一代。
好久沒看遺傳演算法了,上邊的有些術語是我自己編的,看懂就好
還有,你的程序不完全,你能把這個完整的遺傳演算法代碼給我嗎,我感覺這個程序寫的很簡潔,非常好。我的郵箱[email protected]
另外你用這個程序算做什麼?一般智能演算法解決解決問題具有隨機性,因此很難對誤差做出評價,這也是應用受到阻礙的主要原因,如果在解決具體問題的時候,還是優先考慮定量演算法的。
希望我的回答對你有所幫助。
③ 機器學習演算法選擇問題
你這個類似故障分類問題了。分以下兩種情況給你提供個思路吧:
1.如果你的數據是有標簽的,那就可以做有監督的機器學習了。
就是你的數據樣本是某時刻各種屬性值,標簽是此時刻是否有零件有故障以及哪個零件故障。
可以選用的模型有:LogisticRegression、SVM、NaiveBayes、DecisionTree、KNN等,較淺的神經網路也是可以的。
2.如果你的數據沒有標簽,就不太好辦了,可以試試無監督的聚類方法看看有沒有什麼發現。如Kmeans。
3.我做過的故障分類是有監督的,零件屬於某個子系統,子系統又屬於某個系統。我先對系統建模,再對子系統建模,再對零件建模,逐步定位到具體問題。
4.如果你的數據真的是無標簽的,另外給你提供個線索,可以去研究下自編碼網路。
④ 求教:蟻群演算法選擇最短路徑問題
這個例子其實是當初數模比賽時用來完成碎片拼接的,但其所用到原理還是求解最短路徑的原理。但這里的最短路徑和數據結構中最短路徑有一定的區別。在數據結構中,對於最短路徑的求解常用的一般有Dijkstra演算法與Floyd演算法,但對於要求出一條經過所有的點的並且要求路徑最短,這些演算法還是有一定的局限性的。而蟻群演算法則很好地滿足了這些條件。話說回來,很想吐槽一下網路流傳的一些蟻群演算法的例子,當初學習這個時候,身邊也沒有相關的書籍,只好到網上找例子。網上關於這個演算法源代碼的常見的有2個版本,都是出自博客,但是在例子都代碼是不完整的,缺失了一部分,但就是這樣的例子,居然流傳甚廣,我很好奇那些轉載這些源碼的人是否真的有去學習過這些,去調試過。當然,我下面的例子也是無法直接編譯通過的,因為涉及到圖像讀取處理等方面的東西,所以就只貼演算法代碼部分。但是對於這個問題蟻群演算法有一個比較大的缺點,就是收斂很慢,不過對於數量小的路徑,效果還是很好的。function bestqueue =aco1(nt,nc_max,m ,st, sd ,Alpha ,Beta ,Rho ,Q,gethead,getend)%參數解釋:%nt 路徑所經過的點的個數;%nc_max 迭代的次數;%m 螞蟻的個數;%st 起點序號;%sd 終點序號;%Alpha 信息素系數;�ta 啟發因子系數;%Rho 蒸發系數;% Q 信息量;%gethead getend 是用來求距離矩陣的,可根據實際情況修改
% nt = 209;%碎片個數full = zeros(nt,nt);tic;%初始化距離矩陣for i =1:nt for t = 1:nt if i ~= t full(i,t) = sum(abs(getend(:,i) - gethead(:,t))); else full(i,t) = inf; end endend% a =full(156,187)eta = 1./full;%啟發因子,取距離的倒數% eta% e = eta(4,2)tau = ones(nt,nt);%信息素矩陣% tabu = zeros(nt,nt);%禁忌矩陣,取螞蟻數量和碎片數量一致,以減少迭代次數nc =1;%初始化迭代次數;rbest=zeros(nc_max,nt);%各代最佳路線rbest(:,1) = (linspace(st,st,nc_max))';rbest(:,nt) =(linspace(sd,sd,nc_max))'; lbest=zeros(nc_max,1);%各代最佳路線的長度pathlen = 0;%臨時記錄每代最佳路線長度stime = 1;%記錄代數進度for i = 1:nc_max % 代數循環 delta_tau=zeros(nt,nt);%初始化改變數 stime for t = 1:m % 對螞蟻群體的循環, tabu=zeros(1,nt);%禁忌向量,標記已訪問的碎片,初試值設為0,訪問之後則變為1; viseted = zeros(1,nt);%記錄已訪問的元素的位置 tabu(st) = 1;%st為起點,在此表示為碎片矩陣的編號,因為已經將蟻群放在起點,故也應將禁忌向量和位置向量的狀態進行修改 tabu(sd) =1;%同上 visited(nt) = sd ;%同上; visited(1) = st;%同上; ht = 0; for r = 2:nt-1 %記錄了還沒訪問的圖片編號 vp = 1;%visited指示量 pp = [];%置空的概率向量 jc = 0; %獲取尚未訪問的位置的向量。 wv = zeros( nt -2 - ht ); for k =1 : nt if tabu(k) == 0 jc = jc +1; wv(jc) = k; end end% a =(tau(visited(end),ju(3))^Alpha)*(eta(visited(end),ju(3))^Beta)% visited(end) %計算選擇的概率 for k=1:length(wv) pp(k)=(tau(visited(vp),wv(k))^Alpha)*(eta(visited(vp),wv(k))^Beta);%下一張碎片的選擇概率計算,p =(信息素^信息素系數)*(啟發因子^啟發因子系數) end pp=pp./(sum(pp));%歸一化 pcum =cumsum(pp); psl = find(pcum >= rand);%輪盤賭法 to_visit= wv(psl(1)) ;%完成選點 tabu(to_visit) =1; visited(r) = to_visit; ht =ht +1;%已訪問碎片個數變化 vp =vp+1; end %路徑變化信息 %對單個螞蟻的路徑進行統計 sum1 =0; for pr = 1:nt -1 x = visited(pr); y = visited(pr+1) ; sum1 =sum1 + full(x,y); end% vcell{t} =visited;%元胞記錄每個螞蟻的路徑,即碎片順序;% msum(t) = sum1; %信息素變化; for ww=1:(nt-1) delta_tau(visited(ww),visited(ww+1))=delta_tau(visited(ww),visited(ww+1)) + Q/sum1; end% delta_tau(visited(end),visited(1))=delta_tau(visited(end),visited(1))+Q/(sum1/100);% if t == m & i == nc_max % bestqueue = visited% end if t == m bestqueue = visited end end tau=(1-Rho).*tau+delta_tau; %完成信息素的更新,找出現有的最新的最佳路徑,即信息素最多的路徑; stime =stime +1;end toc;