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 。(这里所写的所有算法参数使得算法可能对大规模一些的测试样例有好一点点的结果)

ResultTime(s)
p1902420.61
p2805619.53
p3944420.37
p41175420.56
p5942520.13
p6796620.57
p71004519.98
p81162120.58
p9863719.89
p10761720.32
p11977119.90
p121037320.10
p13937943.32
p14739443.53
p15993643.42
p161225945.25
p17949846.36
p18730645.54
p19940046.45
p201167346.13
p21875545.58
p22772544.22
p23958443.19
p241147844.03
p2512587143.66
p2611305152.75
p2714592142.35
p2816299132.92
p2913777124.52
p3012371131.54
p3114587130.54
p3217775132.95
p3313282137.83
p3411653138.18
p3513596139.97
p3616898136.84
p3712459135.75
p3811295125.29
p3913536122.03
p4015203126.16
p41719229.29
p42621655.43
p43584576.63
p44759429.28
p45689452.86
p46641772.98
p47688027.68
p48679951.53
p49656472.77
p50920427.91
p51831761.33
p52990829.70
p53959260.13
p54980029.79
p55897961.95
p5622932157.19
p5729771158.61
p5842190155.72
p5933111162.50
p6022523157.12
p6129021155.06
p6239131150.16
p6331067158.76
p6422012151.67
p6527011158.99
p6635986171.32
p6730207172.71
p6823228171.35
p6927965170.76
p7041475166.52
p7131348185.35

code
solution

 


 

贪婪算法

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

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

实验结果如下:

ResultTime(s)
p1168440.00105
p2136440.00090
p3148440.00097
p4160440.00105
p5138830.00129
p6134590.00109
p7150590.00202
p8166590.00129
p9141270.00095
p10122510.00095
p11134510.00090
p12146510.00090
p13137990.00156
p14106400.00152
p15122400.00174
p16138400.00156
p17137550.00179
p18108080.00256
p19124080.00220
p20140080.00176
p21161450.00163
p22137640.00158
p23151640.00151
p24165640.00148
p25524400.00969
p26515330.00670
p27533330.00838
p28551330.00638
p29389570.00910
p30457840.00744
p31479840.00737
p32501840.00780
p33640300.00669
p34475760.00844
p35491760.00675
p36507760.00966
p371021250.00717
p38637230.00777
p39647230.00695
p40657230.01497
p41102370.00170
p42118900.00265
p4383180.00481
p44122830.00155
p45114670.00256
p4689000.00298
p47108530.00163
p4898970.00280
p4988090.00428
p50149690.00172
p51108160.00310
p52162770.00167
p53168110.00302
p54150300.00564
p55136490.00349
p56419000.01262
p57467000.01061
p58579000.01346
p59406560.01292
p60472080.01167
p61505080.01255
p62582080.01311
p63426370.01151
p64468910.01066
p65492910.00990
p66548910.00984
p67467720.01119
p68501040.01127
p69531040.00906
p70601040.00939
p71392530.00981

code
solution

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值