Capacitated Facility Location Problems
代碼都位於我的Github上,請點擊這裏查看
https://github.com/Gongzq5/Capacitated-Facility-Location-Problems
文章目錄
問題背景
Capacitated Facility Location Problem
- Suppose there are n facilities and m customers. We wish to choose:
- which of the n facilities to open
- the assignment of customers to facilities
- The objective is to minimize the sum of the opening cost and the assignment cost.
- The total demand assigned to a facility must not exceed its capacity.
Problem Instance
問題參考
這個網站:http://www.di.unipi.it/optimize/Data/MEX.html
包含了問題的已知最優解
問題求解
解法1:模擬退火 SA
代碼:
該解法代碼文件位於 src/SA.cpp 中。
簡介
就是普通的模擬退火,進行了如下的一些改進,並且參數經過了多次試驗性的調整;
- 鄰域搜索策略:
採用5種鄰域搜索策略
- 隨機將一個客戶移動到另一個倉庫
- 隨機改變一個倉庫的狀態
- 若該倉庫是打開的,那麼嘗試將該倉庫的所有用戶分配給其他倉庫,然後關閉它;如果無法將所有用戶都分配走,那麼不恢復已被挪走的用戶,也不改變該倉庫的狀態;
- 若該倉庫是關閉的,那麼將該倉庫打開,並且給這個倉庫隨機分配一個客戶;
- 隨機選擇2個客戶交換倉庫
- 隨機選擇3個客戶輪換倉庫
- 隨機選擇4個客戶輪換倉庫
以上的策略在執行後都會驗證,如果被挪走客戶的倉庫此時沒有任何一個其他客戶使用,那麼將其關閉。
- 額外的改進:
-
降溫開始時記錄一個閾值,在多次迭代不發生改變時,將溫度升高至該閾值,然後閾值減半;
-
根據問題規模確定搜索次數(內循環次數),可以有效地處理問題規模增長後效果變差的情況。
基本參數設置
參數 | 設置 | 備註 |
---|---|---|
初溫 | 初始溫度 | |
降溫速率 | 每輪循環後 | |
概率接受函數 | 隨機數小於該值時接受差解 | |
內循環次數 | 初值根據問題規模確定,每次增加到倍 |
解法2:貪心+局部搜索 Greedy + Local search
代碼
該解法代碼文件位於 src/GreedyLocalSearch.cpp 中。
簡介
首先寫了貪心的算法,貪心的算法在 src/GreedyLocalSearch.cpp 文件中有一個單獨的函數可供查看;
然後寫了局部搜索的算法;
單獨貪心和局部搜索的結果都不是很好,想到可以將兩者結合起來進行計算。首先先使用貪心法求一個初始解,然後使用局部搜索在此初始解附近迭代,試圖找到最優解;
局部搜索使用的鄰域搜索策略和模擬退火是相同的。
額外的改進:
-
爲了避免問題的規模增加後代碼運行次數不足的情況,我增加了根據問題規模決定循環次數的代碼;
int problemSize = instance.customerNum * instance.facilityNum; for (int _i; _i < problemSize * 2000; _i++) {...}
-
爲了避免陷入局部最優,我增加了接受差解的代碼,以期跳出局部最優;
- 首先將接受差解的概率設置爲0;
- 在限定的循環次數內,如果有一定次數沒有發現更優的解,會線性的增加接受差解的概率;
- 由於參數的設定機制,接受差解的概率最多不會超過0.2,在實踐中,通常不會超過0.01。但是取得的效果是顯著的,在陷入局部最優(可能是全局最優)後會以較大的概率跳出該解,整個解檢索的過程大致呈鋸齒狀分佈;
接受差解概率 badAcception = 0 FOR i FROM 0 TO (problemSize * 2000) {生成新解} IF {新解效果好} THEN {接收新解} badAcception = 0 ELSE {以概率badAcception接受差解} IF {不改變的次數大於 problemSize} THEN badAcception += 0.0001; END IF END IF END FOR
基本參數設置
參數 | 設置 | 備註 |
---|---|---|
問題規模 | customerNum * facilityNum |
問題規模爲客戶數量乘以工廠的數量,用來衡量該問題的計算規模 |
差解接受概率 | 0 | 初值爲0,不接受差解;每n次不產生新解則將其遞增0.0001 |
附貪心算法的策略:
每次從客戶的角度出發,貪心離他最近的工廠;
其判斷到每個工廠的代價,計算爲
IF facility[j] is open THEN
cost = assignment cost
ELSE
cost = assignment cost + opening cost
END IF
每次判斷一個用戶,如果該用戶得到的最小代價是一個未打開的工廠的,那麼就把這個工廠打開;如果是一個已打開的工廠,那麼就只需要把用戶指向這個工廠就好了。
實驗結果
考慮到隨機算法效果的隨機性,爲了充分考量算法的效果,我對每個測例進行了三次運行,結果放在結果文件夾的allSolutions文件夾中(命名爲p1(1), p1(2)…),並挑出了其中最好的解放在optimizeSolutions文件夾中。
結果表格請查看 result.md 文件;
我還額外提供了一個結果矩陣的彙總的,命名爲 summary。
鏈接如下:
模擬退火 | 貪心+局部搜索 | |
---|---|---|
所有實驗解 | 模擬退火三次實驗的所有結果 | 局部搜索三次實驗的所有結果 |
所有最優解 | 模擬退火每個測例的最優解 | 局部搜索每個測例的最優解 |
結果彙總 | 模擬退火每個測例具體結果的彙總 | 局部搜索每個測例具體結果的彙總 |
結果表格 | 模擬退火實驗結果的表格 | 局部搜索實驗結果的表格 |
以下附結果表格
模擬退火結果如下
Result | Times(s) | |
---|---|---|
p1 | 8848 | 8 |
p2 | 7914 | 8 |
p3 | 9314 | 8 |
p4 | 10795 | 6 |
p5 | 8838 | 8 |
p6 | 7777 | 7 |
p7 | 9488 | 7 |
p8 | 11088 | 7 |
p9 | 8593 | 5 |
p10 | 7627 | 7 |
p11 | 8938 | 7 |
p12 | 10252 | 8 |
p13 | 8294 | 18 |
p14 | 7137 | 17 |
p15 | 8862 | 17 |
p16 | 10524 | 20 |
p17 | 8294 | 17 |
p18 | 7152 | 16 |
p19 | 8907 | 16 |
p20 | 10514 | 17 |
p21 | 8171 | 17 |
p22 | 7178 | 16 |
p23 | 8774 | 14 |
p24 | 10463 | 19 |
p25 | 11639 | 106 |
p26 | 10776 | 99 |
p27 | 12336 | 101 |
p28 | 13736 | 105 |
p29 | 12548 | 102 |
p30 | 11337 | 139 |
p31 | 13378 | 189 |
p32 | 15376 | 182 |
p33 | 11632 | 101 |
p34 | 10635 | 103 |
p35 | 12235 | 100 |
p36 | 13835 | 99 |
p37 | 11326 | 99 |
p38 | 10594 | 98 |
p39 | 11951 | 107 |
p40 | 13059 | 125 |
p41 | 6737 | 11 |
p42 | 5755 | 32 |
p43 | 5302 | 32 |
p44 | 7107 | 14 |
p45 | 6580 | 25 |
p46 | 5980 | 36 |
p47 | 7077 | 13 |
p48 | 6239 | 25 |
p49 | 5609 | 38 |
p50 | 8848 | 13 |
p51 | 7414 | 36 |
p52 | 9246 | 15 |
p53 | 8531 | 38 |
p54 | 8838 | 23 |
p55 | 7654 | 34 |
p56 | 21748 | 140 |
p57 | 26379 | 155 |
p58 | 38059 | 160 |
p59 | 27694 | 143 |
p60 | 21241 | 137 |
p61 | 25596 | 139 |
p62 | 33662 | 143 |
p63 | 25397 | 142 |
p64 | 21400 | 164 |
p65 | 25794 | 137 |
p66 | 32688 | 145 |
p67 | 25231 | 142 |
p68 | 22086 | 137 |
p69 | 26100 | 143 |
p70 | 33316 | 147 |
p71 | 25679 | 144 |
局部搜索結果如下
Result | Times(s) | |
---|---|---|
p1 | 8848 | 6s |
p2 | 7914 | 5s |
p3 | 9314 | 6s |
p4 | 10859 | 7s |
p5 | 8838 | 6s |
p6 | 7777 | 5s |
p7 | 9488 | 6s |
p8 | 11088 | 6s |
p9 | 8462 | 7s |
p10 | 7617 | 5s |
p11 | 8932 | 6s |
p12 | 10138 | 7s |
p13 | 8252 | 13s |
p14 | 7182 | 12s |
p15 | 8862 | 14s |
p16 | 10612 | 17s |
p17 | 8227 | 13s |
p18 | 7188 | 12s |
p19 | 8887 | 12s |
p20 | 10513 | 13s |
p21 | 8068 | 13s |
p22 | 7154 | 13s |
p23 | 8806 | 13s |
p24 | 10327 | 14s |
p25 | 11639 | 77s |
p26 | 10781 | 78s |
p27 | 12340 | 77s |
p28 | 13736 | 79s |
p29 | 12450 | 153s |
p30 | 11391 | 155s |
p31 | 13367 | 217s |
p32 | 15387 | 245s |
p33 | 11706 | 76s |
p34 | 10635 | 73s |
p35 | 12235 | 75s |
p36 | 13835 | 75s |
p37 | 11258 | 116s |
p38 | 10551 | 48s |
p39 | 11824 | 69s |
p40 | 13024 | 72s |
p41 | 6640 | 7s |
p42 | 5750 | 14s |
p43 | 5369 | 20s |
p44 | 7462 | 7s |
p45 | 6396 | 13s |
p46 | 6083 | 20s |
p47 | 6836 | 9s |
p48 | 5910 | 14s |
p49 | 5584 | 19s |
p50 | 8861 | 8s |
p51 | 7471 | 17s |
p52 | 9253 | 7s |
p53 | 8589 | 18s |
p54 | 8834 | 19s |
p55 | 7663 | 21s |
p56 | 22384 | 67s |
p57 | 27321 | 68s |
p58 | 38651 | 69s |
p59 | 28015 | 69s |
p60 | 23122 | 67s |
p61 | 25995 | 66s |
p62 | 34816 | 67s |
p63 | 25279 | 68s |
p64 | 23637 | 66s |
p65 | 25958 | 134s |
p66 | 33124 | 68s |
p67 | 27487 | 68s |
p68 | 22317 | 68s |
p69 | 25258 | 68s |
p70 | 33102 | 68s |
p71 | 26433 | 71s |