问题概述
容量受限的设施选址问题:
有 n 个设施和 m 个顾客,我们希望选出
- n 个设施中哪些要开启
- 将顾客分配到某个设施
目标是最小化开启费用和分配费用的和。
注意:分配给一个设施的总需求不能超过它的容量。
求解结果要求:
红线指顾客被分配到哪个设施。例如第一个人去了第一个设施,第二个人去了第三个设施,以此类推。
问题实例的数据解释:
问题求解框架
使用 c++ 语言求解(代码Github 地址:code)
将问题抽象为一个类,用类变量存储相应的数据和求解结果,通过类方法实现算法,对变量进行算法操作,得出结果。
主程序只需用问题实例的数据创建一个问题实例,调用相应的方法即可完成对该问题实例的求解。
贪婪算法求解
贪婪算法是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是最好或最优的算法。
在本题中,一种贪婪策略是在为每个顾客分配设施时,选择容量足够且分配费用最小的设施。算法代码如下:
Result Table:
Result | Time(s) | |
---|---|---|
p1 | 10355 | 0.004 |
p2 | 9041 | 0.005 |
p3 | 11041 | 0.004 |
p4 | 13041 | 0.004 |
p5 | 10827 | 0.006 |
p6 | 9513 | 0.009 |
p7 | 11513 | 0.005 |
p8 | 13513 | 0.004 |
p9 | 10355 | 0.003 |
p10 | 9041 | 0.004 |
p11 | 11041 | 0.003 |
p12 | 13041 | 0.004 |
p13 | 11915 | 0.007 |
p14 | 9426 | 0.008 |
p15 | 13026 | 0.01 |
p16 | 16626 | 0.008 |
p17 | 11915 | 0.007 |
p18 | 9426 | 0.006 |
p19 | 13026 | 0.007 |
p20 | 16626 | 0.007 |
p21 | 11915 | 0.007 |
p22 | 9426 | 0.006 |
p23 | 13026 | 0.006 |
p24 | 16626 | 0.007 |
p25 | 16655 | 0.029 |
p26 | 14125 | 0.028 |
p27 | 18925 | 0.028 |
p28 | 23725 | 0.029 |
p29 | 17487 | 0.03 |
p30 | 14750 | 0.028 |
p31 | 19950 | 0.033 |
p32 | 25150 | 0.03 |
p33 | 17013 | 0.028 |
p34 | 14380 | 0.029 |
p35 | 19380 | 0.03 |
p36 | 24380 | 0.031 |
p37 | 16597 | 0.03 |
p38 | 14067 | 0.027 |
p39 | 18867 | 0.028 |
p40 | 23667 | 0.029 |
p41 | 8812 | 0.007 |
p42 | 10681 | 0.011 |
p43 | 13592 | 0.014 |
p44 | 12171 | 0.006 |
p45 | 12949 | 0.011 |
p46 | 14215 | 0.013 |
p47 | 13780 | 0.006 |
p48 | 12854 | 0.01 |
p49 | 13633 | 0.014 |
p50 | 9983 | 0.007 |
p51 | 10848 | 0.013 |
p52 | 15442 | 0.007 |
p53 | 14438 | 0.022 |
p54 | 14894 | 0.011 |
p55 | 14585 | 0.018 |
p56 | 28184 | 0.057 |
p57 | 37184 | 0.04 |
p58 | 58184 | 0.04 |
p59 | 43423 | 0.038 |
p60 | 28184 | 0.041 |
p61 | 37184 | 0.038 |
p62 | 58184 | 0.036 |
p63 | 43423 | 0.037 |
p64 | 28184 | 0.037 |
p65 | 37184 | 0.038 |
p66 | 58184 | 0.035 |
p67 | 43802 | 0.039 |
p68 | 28184 | 0.037 |
p69 | 37184 | 0.037 |
p70 | 58184 | 0.038 |
p71 | 43423 | 0.038 |
Detailed Solution:
模拟退火算法求解
- 初始化:用贪婪算法生成的解作为初始状态。
- 迭代过程
- 为一个顾客随机分配另一个设施,以此产生一个新解,计算新解与当前解的差值;
- 判断新解是否被接受,判断的依据是一个接受准则,最常用的接受准则是Metropolis准则:若Δt′<0则接受S′作为新的当前解S,否则以概率exp(-Δt′/T)接受S′作为新的当前解S。
- 当新解被确定接受时,用新解代替当前解,这只需将当前解中对应于产生新解时的变换部分予以实现,同时修正目标函数值即可。
- 停止准则:温度T降至某最低值时,完成给定数量迭代中无法接受新解,停止迭代,接受当前寻找的最优解为最终解。
- 退火方案:在某个温度状态T下,当一定数量的迭代操作完成后,降低温度T,在新的温度状态下执行下一个批次的迭代操作。
Result Table:
Result | Time(s) | |
---|---|---|
p1 | 10245 | 0.256 |
p2 | 8917 | 0.25 |
p3 | 10717 | 0.252 |
p4 | 12517 | 0.28 |
p5 | 10217 | 0.263 |
p6 | 8917 | 0.258 |
p7 | 10717 | 0.274 |
p8 | 12517 | 0.219 |
p9 | 10217 | 0.218 |
p10 | 8917 | 0.219 |
p11 | 10858 | 0.211 |
p12 | 12604 | 0.203 |
p13 | 9589 | 0.254 |
p14 | 8298 | 0.234 |
p15 | 10207 | 0.256 |
p16 | 12082 | 0.231 |
p17 | 9406 | 0.256 |
p18 | 8260 | 0.263 |
p19 | 10465 | 0.239 |
p20 | 12043 | 0.237 |
p21 | 9543 | 0.245 |
p22 | 8319 | 0.231 |
p23 | 10346 | 0.245 |
p24 | 12597 | 0.234 |
p25 | 14515 | 0.835 |
p26 | 12133 | 0.842 |
p27 | 15052 | 0.728 |
p28 | 18919 | 0.694 |
p29 | 14480 | 0.723 |
p30 | 12167 | 0.726 |
p31 | 15519 | 0.765 |
p32 | 18238 | 0.733 |
p33 | 14570 | 0.71 |
p34 | 12119 | 0.705 |
p35 | 15529 | 0.695 |
p36 | 18929 | 0.698 |
p37 | 14016 | 0.785 |
p38 | 12122 | 0.762 |
p39 | 15052 | 0.726 |
p40 | 18919 | 0.703 |
p41 | 8714 | 0.404 |
p42 | 8581 | 0.371 |
p43 | 8008 | 0.33 |
p44 | 11982 | 0.394 |
p45 | 10576 | 0.375 |
p46 | 8436 | 0.331 |
p47 | 12367 | 0.408 |
p48 | 10681 | 0.379 |
p49 | 8747 | 0.34 |
p50 | 8492 | 0.44 |
p51 | 7918 | 0.468 |
p52 | 14015 | 0.443 |
p53 | 12719 | 0.471 |
p54 | 12632 | 0.452 |
p55 | 11190 | 0.485 |
p56 | 27481 | 0.904 |
p57 | 35841 | 0.904 |
p58 | 54008 | 0.913 |
p59 | 41037 | 0.891 |
p60 | 26985 | 0.897 |
p61 | 35151 | 0.925 |
p62 | 54026 | 0.909 |
p63 | 40408 | 0.903 |
p64 | 27051 | 0.918 |
p65 | 35335 | 0.917 |
p66 | 54113 | 0.908 |
p67 | 41424 | 0.914 |
p68 | 27045 | 0.904 |
p69 | 34420 | 0.895 |
p70 | 52673 | 0.894 |
p71 | 41037 | 0.896 |
Detailed Solution
(后面的图略)