Project CFLP

 
  本次项目使用两种算法完成,一为遗传算法,二为贪婪算法。以下分别阐述两种算法的框架和实验结果。


 

遗传算法

  • 约定

    • N N N 表示顾客(customer) 总数
    • M M M 表示设施(facility) 总数
    • c i j c_{ij} cij 表示将 i i i 号顾客分配到 j j j 号设施的 cost
    • C j C_j Cj 表示开放 j j j 号设施的 cost
    • d i d_i di 表示 i i i 号顾客的 demand
    • D j D_j Dj 表示 j j j 号设施的 capacity
  • 编码方式
      使用长度为 N N N 的一维数组 X X X 来表示一个可能的解,第 i ( i = 0 , 1 , ⋯   , N − 1 ) i(i=0,1,\cdots,N-1) i(i=0,1,,N1) 位数字 X i X_i Xi 表示 i i i 号顾客被分配到设施 X i X_i Xi ( X i ≤ M − 1 ) X_i \leq M-1) XiM1)

  • 适应度函数
    (1) f ( X ) = G − ( C ( X ) + ∑ j = 0 M − 1 P j ( X ) ) f(X) = G - (C(X) + \sum_{j=0}^{M-1} P_j(X)) \tag{1} f(X)=G(C(X)+j=0M1Pj(X))(1)
      其中, G G G为一个足够大的常数, C ( X ) C(X) C(X)为目标函数,即总的 cost, P j ( x ) P_j(x) Pj(x)为设施 j j j 容积超出的惩罚函数。两个函数定义如下:
    (2) C ( X ) = ∑ i = 0 N − 1 c i X i C(X) = \sum_{i=0}^{N-1} c_{iX_{i}} \tag{2} C(X)=i=0N1ciXi(2)
    (3) P j ( X ) = { α ( D j ′ − D j ) v j ′ , 当 D j ′ > D j ( D j ′  为  j  设施中实际的总demand) 0 , 当 D j ′ ≤ D j P_j(X) = \begin{cases} \alpha(D'_j - D_j)v'_j, & \text {当$D'_j>D_j$($D'_j$ 为 $j$ 设施中实际的总demand)} \\ 0, & \text {当$D'_j\leq D_j$} \tag{3} \end{cases} Pj(X)={α(DjDj)vj,0,Dj>Dj(Dj  j 设施中实际的总demand)DjDj(3)
      这里的 α \alpha α 为惩罚系数; v j ′ v'_j vj 为每个设施已分配的顾客中, c o s t d e m a n d \frac {cost}{demand} demandcost最大的值。
      另外, ( 1 ) (1) (1) 式若计算结果为负数,则 f ( X ) f(X) f(X) 为0。

  • 初始化种群
      首先,计算出每个顾客到每个设施的一个比例 v i j = c i j d i v_{ij} = \frac {c_ij}{d_i} vij=dicij,即 c o s t d e m a n d \frac {cost}{demand} demandcost 的值。
      从种群的多样性考虑,将种群的大小设为设施数 M M M β ( β ≥ 2 ) \beta(\beta \geq 2) β(β2),并且设计让每一个设施在初始种群中开放的次数至少为 β \beta β 次(让每个设施都有开放的机会)。
      通过循环,生成初始种群中的每一个个体。在第 k ( k = 1 , 2 , ⋯   , β × M ) k(k=1, 2, \cdots,\beta ×M) k(k=1,2,,β×M) 次循环中:

    • 首先开放第一个设施 t t t t = ⌊ k − 1 β ⌋ t=\lfloor{\frac{k-1}{\beta}}\rfloor t=βk1 ,然后在 t t t 号设施的前 3 个最小的 v v v 中随机选择一个分配到该设施(贪心),并开始记录当前已开放的设施的总 capacity 。
    • 遍历分配每一个未被分配的顾客到一个设施中。
      • 设置一个概率 p p p ,表示接下来的一个顾客将要被分配到的设施是从已开放的设施中选择还是从全体设施中选择,以此获取一个候选列表。概率 p p p 根据当前已开放的设施的总 capacity 是否大于总体顾客的 demand 来设置。
      • 对要分配的顾客 i i i,从候选列表中选出一个设施 j j j,使得 v i j v_{ij} vij 对于候选列表中的那些可容纳该顾客的设施是最小的,将顾客 i i i 分配到设施 j ( X i = j ) j(X_i = j) j(Xi=j)贪心)。若顾客 i i i 不能被分配到候选列表中的任何一个设施,则随机分配到候选列表以外的一个设施中(新开一个设施)。

  这样,初始种群中的每一个个体都是合法的,并在初始化种群中应用一些贪心策略,可能会得到更好的结果。

  • 选择
      采用锦标赛策略(Tournament Selection),随机选择的个体数设为 2 。

  • 交叉
      交叉操作设计得较为简单,即随机在两个个体中选择一段进行交换。

  • 变异
      随机选择 n ( n = 1 , 2 , ⋯   , ⌊ N 2 ⌋ ) n(n=1,2,\cdots,\lfloor \frac N2 \rfloor) n(n=1,2,,2N) 个顾客,按照各50%的概率将他们分别分配到已开放的设施之一或是全体设施之一。

  • 产生下一代种群
      将父代产生的后代和父代一起组成一个候选池,采用锦标赛策略(Tournament Selection)从候选池中一个个地选择出个体作为下一代,随机选择的个体数设为 ⌊ β × M 3 ⌋ \lfloor \frac {\beta × M}3 \rfloor 3β×M ,即种群数的三分之一。

  • 其他细节

    • 设计总的代数为10000代。
    • 每当20代后最佳结果都没有发生改变时,增加变异概率(+0.1),以期跳出局部最优。

  当然,以上的一些参数数字还可以做各种调整以改进解的质量。以下的实验结果取 α = 1 \alpha=1 α=1 β = 2 \beta=2 β=2 。(这里所写的所有算法参数使得算法可能对大规模一些的测试样例有好一点点的结果)

Result Time(s)
p1 9024 20.61
p2 8056 19.53
p3 9444 20.37
p4 11754 20.56
p5 9425 20.13
p6 7966 20.57
p7 10045 19.98
p8 11621 20.58
p9 8637 19.89
p10 7617 20.32
p11 9771 19.90
p12 10373 20.10
p13 9379 43.32
p14 7394 43.53
p15 9936 43.42
p16 12259 45.25
p17 9498 46.36
p18 7306 45.54
p19 9400 46.45
p20 11673 46.13
p21 8755 45.58
p22 7725 44.22
p23 9584 43.19
p24 11478 44.03
p25 12587 143.66
p26 11305 152.75
p27 14592 142.35
p28 16299 132.92
p29 13777 124.52
p30 12371 131.54
p31 14587 130.54
p32 17775 132.95
p33 13282 137.83
p34 11653 138.18
p35 13596 139.97
p36 16898 136.84
p37 12459 135.75
p38 11295 125.29
p39 13536 122.03
p40 15203 126.16
p41 7192 29.29
p42 6216 55.43
p43 5845 76.63
p44 7594 29.28
p45 6894 52.86
p46 6417 72.98
p47 6880 27.68
p48 6799 51.53
p49 6564 72.77
p50 9204 27.91
p51 8317 61.33
p52 9908 29.70
p53 9592 60.13
p54 9800 29.79
p55 8979 61.95
p56 22932 157.19
p57 29771 158.61
p58 42190 155.72
p59 33111 162.50
p60 22523 157.12
p61 29021 155.06
p62 39131 150.16
p63 31067 158.76
p64 22012 151.67
p65 27011 158.99
p66 35986 171.32
p67 30207 172.71
p68 23228 171.35
p69 27965 170.76
p70 41475 166.52
p71 31348 185.35

code
solution

 


 

贪婪算法

  贪婪算法的设计较为简单,主要是为了做一定程度的对比。

  首先同遗传算法一样,计算出 v i j v_{ij} vij。按照开放的cost的升序给设施排序,按序开放设施,每开放一个设施 k k k,按照该设施对应的 v i k v_{ik} vik 从小到大将相应的顾客分配到该设施,直到不能再分配下一个顾客(即使在这个顾客之后可能还有顾客能够被分配到该设施)。
  当所有顾客都被分配到一个设施后,算法结束。

实验结果如下:

Result Time(s)
p1 16844 0.00105
p2 13644 0.00090
p3 14844 0.00097
p4 16044 0.00105
p5 13883 0.00129
p6 13459 0.00109
p7 15059 0.00202
p8 16659 0.00129
p9 14127 0.00095
p10 12251 0.00095
p11 13451 0.00090
p12 14651 0.00090
p13 13799 0.00156
p14 10640 0.00152
p15 12240 0.00174
p16 13840 0.00156
p17 13755 0.00179
p18 10808 0.00256
p19 12408 0.00220
p20 14008 0.00176
p21 16145 0.00163
p22 13764 0.00158
p23 15164 0.00151
p24 16564 0.00148
p25 52440 0.00969
p26 51533 0.00670
p27 53333 0.00838
p28 55133 0.00638
p29 38957 0.00910
p30 45784 0.00744
p31 47984 0.00737
p32 50184 0.00780
p33 64030 0.00669
p34 47576 0.00844
p35 49176 0.00675
p36 50776 0.00966
p37 102125 0.00717
p38 63723 0.00777
p39 64723 0.00695
p40 65723 0.01497
p41 10237 0.00170
p42 11890 0.00265
p43 8318 0.00481
p44 12283 0.00155
p45 11467 0.00256
p46 8900 0.00298
p47 10853 0.00163
p48 9897 0.00280
p49 8809 0.00428
p50 14969 0.00172
p51 10816 0.00310
p52 16277 0.00167
p53 16811 0.00302
p54 15030 0.00564
p55 13649 0.00349
p56 41900 0.01262
p57 46700 0.01061
p58 57900 0.01346
p59 40656 0.01292
p60 47208 0.01167
p61 50508 0.01255
p62 58208 0.01311
p63 42637 0.01151
p64 46891 0.01066
p65 49291 0.00990
p66 54891 0.00984
p67 46772 0.01119
p68 50104 0.01127
p69 53104 0.00906
p70 60104 0.00939
p71 39253 0.00981

code
solution

你可能感兴趣的:(算法,Algorithm,Algorithm)