1.程式功能描述
基於流量估計,MCKP-MMF演算法便可以找到本地MCKP-MMF的近似解。其基本思想與MMKP-MMF相似,但是相比之下,MCKP-MMF採取了更為簡單的策略從而使之成為一種啟發式演算法並且執行更快。演算法從最小配置開始,並將所有訪問點初始化為活動狀態。此後,演算法在執行的每一輪中發現一個較好的部分解,並將相關的訪問點置為停止狀態,直至所有訪問點都成為停止狀態,演算法終止。
某個訪問點可能先後收到來自多個擁塞節點的重新設定影響半徑的要求,此時為了滿足頻寬消耗最大的節點的頻寬限制,訪問點需要將其新影響半徑設定為其中最小的一個。一種簡單的方法是每次收到這樣的請求之後,將其中包含的新影響半徑與訪問點當前影響半徑比較,如果新影響半徑較小則修改當前影響半徑為新影響半徑,否則訪問點保持當前影響半徑。這樣作的一個副作用是訪問點的影響半徑將隨時間增長而變小。從另一方面,節點由於僅透過本地資訊為與之相關的訪問點確定影響半徑,可能無法得到訪問點真正的最優影響半徑。為了消除這個副作用並幫助訪問點跳出本地最優狀態從而更接近全域性最優配置,每個訪問點需要週期性的增加其影響半徑。
2.測試軟體版本以及執行結果展示
MATLAB2022a版本
3.核心程式
while(times <Stimes) figure(2); plot(Xn,Yn,'b.'); hold on; plot(Xm,Ym,'r.'); hold on; times times = times + 1; SATVs = SATV*ones(1,N); Tpk = zeros(M,1); %代價函式 NEXT_ptr = 0; NEXT_Set = ones(1,M); while(NEXT_ptr<= M) %所有活動訪問點半徑均被增加且所得為合適解 %計算代價函式 for j = 1:M for i1 = 1:N d = sqrt( (Xn(i1) - Xm(j))^2 + (Yn(i1) - Ym(j))^2 ); %判斷是否在一定範圍之內 if d <= Rs(j) %進行資源分配 Tpk(j) = Tpk(j) + Requst(j,i1); else Tpk(j) = Tpk(j); end end end [A,I] = sort(Tpk); if A > 0 %選擇最小的一個 Tpk_min = A(1); Tpk_ind = I(1); NEXT_Set(Tpk_ind) = 0; if feasible(A,rij) == 1 %沒有被違反 Rs(Tpk_ind) = Rs(Tpk_ind) + Step; if (NEXT_Set(Tpk_ind)) == 0 NEXT_ptr = NEXT_ptr; else NEXT_ptr = NEXT_ptr + 1; end else %違反了,則直接退出進入下一個迴圈 NEXT_ptr = M+1; end else %如果流量為0,則說明沒有發生任何請求,其實半徑自動遞增 Tpk_min = A(1); Tpk_ind = I(1); Rs(Tpk_ind) = Rs(Tpk_ind) + Step; end end %多個擁塞節點的重新設定影響半徑 for j = 1:M %表示該訪問點處於第1階段 if FLag(j) == 0 %計算每個節點到訪問點的距離 for i1 = 1:N d = sqrt( (Xn(i1) - Xm(j))^2 + (Yn(i1) - Ym(j))^2 ); %判斷是否在一定範圍之內 if d <= Rs(j) %進行資源分配 SATVs(1,i1) = SATVs(1,i1) - Requst(j,i1); else SATVs(1,i1) = SATVs(1,i1); end %每次請求完之後,判斷是否擁堵 if SATVs(1,i1) <= 0%表示擁堵 saturated_state{j,i1} = [1,Rs',Xm(j),Ym(j),Xn(i1),Yn(i1)]; FLag(j) = 1; else saturated_state{j,i1} = [0,zeros(1,M),0,0,0,0]; FLag(j) = FLag(j); end end end %******************************************************************** end %繪製模擬結果 figure(3); subplot(421); plot(R(1,:),'b','linewidth',2); xlabel('TIMES'); ylabel('Radius'); grid on; title('資源點1半徑請求變化'); subplot(422); plot(R(2,:),'b','linewidth',2); xlabel('TIMES'); ylabel('Radius'); grid on; title('資源點2半徑請求變化'); subplot(423); plot(R(3,:),'b','linewidth',2); xlabel('TIMES'); ylabel('Radius'); grid on; title('資源點3半徑請求變化'); subplot(424); plot(R(4,:),'b','linewidth',2); xlabel('TIMES'); ylabel('Radius'); grid on; title('資源點4半徑請求變化'); subplot(425); plot(R(5,:),'b','linewidth',2); xlabel('TIMES'); ylabel('Radius'); grid on; title('資源點5半徑請求變化'); subplot(426); plot(R(6,:),'b','linewidth',2); xlabel('TIMES'); ylabel('Radius'); grid on; title('資源點6半徑請求變化'); subplot(427); plot(R(7,:),'b','linewidth',2); xlabel('TIMES'); ylabel('Radius'); grid on; title('資源點7半徑請求變化'); subplot(428); plot(R(8,:),'b','linewidth',2); xlabel('TIMES'); ylabel('Radius'); grid on; title('資源點8半徑請求變化'); %繪製模擬結果 figure(4); subplot(421); plot(TPK(1,10:end),'b','linewidth',2); xlabel('TIMES'); ylabel('代價函式'); grid on; title('資源點1代價函式'); subplot(422); plot(TPK(2,10:end),'b','linewidth',2); xlabel('TIMES'); ylabel('代價函式'); grid on; title('資源點2代價函式'); subplot(423); plot(TPK(3,10:end),'b','linewidth',2); xlabel('TIMES'); ylabel('代價函式'); grid on; title('資源點3代價函式'); subplot(424); plot(TPK(4,10:end),'b','linewidth',2); xlabel('TIMES'); ylabel('代價函式'); grid on; title('資源點4代價函式'); subplot(425); plot(TPK(5,10:end),'b','linewidth',2); xlabel('TIMES'); ylabel('代價函式'); grid on; title('資源點5代價函式'); subplot(426); plot(TPK(6,10:end),'b','linewidth',2); xlabel('TIMES'); ylabel('代價函式'); grid on; title('資源點6代價函式'); subplot(427); plot(TPK(7,10:end),'b','linewidth',2); xlabel('TIMES'); ylabel('代價函式'); grid on; title('資源點7代價函式'); subplot(428); plot(TPK(8,10:end),'b','linewidth',2); xlabel('TIMES'); ylabel('代價函式'); grid on; title('資源點8代價函式'); 12_008m
4.本演算法原理
演算法的執行可以分為兩個階段。第一階段是通常所謂的慢啟動階段,在該階段,各個sink開始於最小半徑的請求,然後以某種速度增加其請求半徑,直到演算法發現一個潛在的瓶頸節點,此時相關sink將收到<saturated>訊息。演算法中initRadius過程負責確定每次增加請求半徑。某個sink收到一個<saturated>訊息之後重新設定其請求半徑為某一較小值以試圖緩解擁塞。 resetRadius過程負責在收到<saturated>訊息之後計算新的請求半徑。該sink隨後進入演算法的第二階段。進入第二階段的sink將週期性的試圖增加其請求半徑,以取得最優 max-min公平請求半徑。此步驟由increaseRadius過程處理。這樣增加的結果是,不久之後該sink再次收到<saturated>訊息並縮小請求半徑,而後再次週期性增加。
所有sink同時發出請求,並將初始半徑設定為最小值。然後所有sink以同步方式增加請求半徑直到網路中某一感測器節點上的資料流量飽和(該節點被稱為瓶頸節點)。當某個感測器節點流量飽和時,覆蓋該節點的所有sink停止增加其請求半徑,但是其它sink繼續增加其請求半徑。當沒有sink可以繼續增加其請求半徑時,演算法結束。我們說此演算法的解為最優解是因為該演算法的解滿足max-min公平性的同時被全域性或區域性最大化。