使用python编写离散型工厂选址问题的遗传算法(课程作业)

离散型工厂选址问题的遗传算法

一、问题描述

1.1 工厂选址问题

​ 工厂选址(facility location),就是确定在何处建厂、仓储中心或建立服务设施。它不仅关系到设施建设的投资和建设速度,而且在很大程度上决定了所提供的产品和服务的成本,从而影响企业的生产管理活动和经济效益。除了少数的原材料采掘企业,如矿产企业、原木采伐企业必须将选址定在相应资源丰富的所在地,绝大多数企业都将面临着不同的选址问题的决策。随着全球制造的出现,现代企业的选址问题涉及的范围已超出某一地区、某一国家了,而是在全球范围内考虑选址的问题。

​ 离散选址是指在有限的侯选位置里面,选取最为合适的一个或一组位置为最优方案,对应的模型叫做离散选址模型。它与连续选址模型的区别在于:它所拥有的侯选方案只有有限个元素,在进行选址时只需对有限个位置进行分析。离散选址问题一般都可以用混合整数规划模型来表示,模型中的目标函数可以采用以选址问题的最短距离为目标,如p-Median问题和p-Center问题及其衍生问题。也可以采用选址问题的最小费用为目标等。

1.2 离散选址模型

​ 给定某一地区所有需求点的地址集合,要求从备选地址中选出一定数目的地址建立工厂,从而建立一系列的配送区域,实现各个需求点的配送,使得在选出点建立的工厂与各需求点形成的配送系统总配送费用最少。为了便于建立模型,需作一定的假设,假设系统满足如下一些条件:

  • 仅在一定的被选对象内考虑新的工厂建厂;

  • 运输费用与运输量成正比;

  • 需求点的需求按区域总计;

  • 工厂生产能力可以满足需求;

  • 各需求点的需求量一定且为己知;

  • 总费用只考虑固定的工厂建址费用和运输费用。

    该选址问题的混合整数规划模型为:
    在这里插入图片描述
    式中, m m m为工厂备选地点的个数; n n n为需求点的个数; p p p为可设置工厂的最大个数; x i j x_{ij} xij;为从工厂 i i i到需求点 j j j的运输量; y i y_i yi为整数变量,当 y i y_i yi=1时表示 i i i地被选中,当 y i y_i yi=0时表示 i i i地未被选中; b j b_j bj为第 j j j地的需求量; a i a_i ai为被选工厂 i i i的建设容量(供应能力); c i j c_{ij} cij为从 i i i地到 j j j地的包括装卸运输费在内的单位运输费用; d i d_i di为被选工厂 i i i的固定费用(包括基本投资费和固定经营费)。
    目标函数(1)中,等式右边第一项是从工厂到需求点的运输成本;第二项是工厂设置的固定成本。式(2)表示从各工厂向某需求点供给的物资总和应满足该需求点的需求量;式(3)表示如果i地点被选中建厂,则从它发出的货物总量不超过它的建设容量(供应能力);式(4)表示选上的工厂个数不得超过原定的最大限额。

二、遗传算法设计

2.1 遗传算法的基本步骤

  • s t e p 1. step1. step1. 遗传编码
  • s t e p 2. step2. step2. 初始种群的生成
  • s t e p 3. step3. step3. 适应度评估检测
  • s t e p 4. step4. step4. W H I L E WHILE WHILE<未满足迭代终止条件> D O DO DO
      1. 选择
      1. 交叉
      1. 变异
      1. 适应度评估检测
  • s t e p 5. step5. step5. E N D   D O END ~DO END DO

2.2 遗传编码

​ 采用二重结构编码对离散工厂选址模型的约束条件进行处理,这种编码方式可以避免无效染色体的产生,提高遗传算法的搜索效率。二重结构编码方法如图1所示。染色体表示的二重结构由变量码和附加码两行组成。上行 s ( k ) s(k) s(k)为变量 y s ( k ) y_{s(k)} ys(k)的附加码, s ( k ) = i s(k)=i s(k)=i,表示工厂备选地的序号,下行为变量 y s ( k ) y_{s(k)} ys(k)对应于附加码 s ( k ) s(k) s(k)的值表示该工厂是否被选中。

附加码 s ( 1 ) s(1) s(1) s ( 2 ) s(2) s(2) s ( k ) s(k) s(k) s ( m ) s(m) s(m)
变量码 y s ( 1 ) y_{s(1)} ys(1) y s ( 2 ) y_{s(2)} ys(2) y s ( k ) y_{s(k)} ys(k) y s ( m ) y_{s(m)} ys(m)
图1 工厂选址的二重结构编码

​ 个体编码时,首先按洗牌方式随机产生附加码 { s ( k ) , k = l , ⋯ &ThinSpace; , m } \{s(k),k=l,\cdots,m\} {s(k),k=l,,m},列于上行;然后随机产生下行的变量码值{0或1},这样构成一个个体的二重结构编码。按照这种方式随机产生初始群体。
​ 由式(2)、式(3)很容易得出约束条件 ∑ j = 1 n b j ⩽ ∑ i = 1 m a i y i \sum\limits_{j=1}^{n}b_{j}\leqslant\sum\limits_{i=1}^{m}a_{i}y_{i} j=1nbji=1maiyi。因此,个体解码时(图1),按照从左到右的顺序,依次考虑变量的附加码,即按照顺序考虑附加码为 s ( k ) s(k) s(k)的工厂。如果 y s ( k ) y_{s(k)} ys(k)为1的工厂容量之和小于所有需求点的需求量之和,则随机产生一个不大于 m m m的自然数 s ( k ) s(k) s(k);如果 y s ( k ) y_{s(k)} ys(k)为0,则强制该数为1,并将附加码为 s ( k ) s(k) s(k)的工厂的容量与处理前变量码为1的工厂的容量相加。按照这种方法处理,直到变量码为1的工厂的容量之和不小于所有需求点的需求量之和为止。

​ 解码算法的步骤为:

  • s t e p 1 : step1: step1: s u m 1 = ∑ i = 1 m y s k a s k , s u m 2 = ∑ j = 1 n b j ; sum_{1}=\sum\limits_{i=1}^{m}y_{s_{k}}a_{s_{k}},sum_{2}=\sum\limits_{j=1}^{n}b_{j}; sum1=i=1myskask,sum2=j=1nbj;

  • s t e p 2 : step2: step2: s u m 1 &lt; s u m 2 , sum_{1}&lt;sum_{2}, sum1<sum2,则执行 s t e p 3 , step3, step3,否则执行 s t e p 4 ; step4; step4

  • s t e p 3 : step3: step3:随机产生一个不大于 m m m的自然数为 s ( k ) , s(k), s(k),如果 y s ( k ) = 0 , y_{s(k)}=0, ys(k)=0,则令 s u m 1 = s u m 1 + a s ( k ) , y s ( k ) = 1 , sum_{1}=sum_{1}+a_{s(k)},y_{s(k)=1,} sum1=sum1+as(k),ys(k)=1,返回 s t e p 2 ; step2; step2;否则继续执行 s t e p 3 ; step3; step3;

  • s t e p 4 : step4: step4:算法终止。

    ​ 对于一个含有8个备选工厂的选址问题,如果随机产生的附加码序列为9、3、1、5、4、6、8、10,2,7,该个体的二重结构编码如图2所示。它对应一个选址方案,变量码为1的工厂被选中,即选择序号为3、5、6,10,7的地址建厂。

93154681027
0101010101
图2 一个个体的二重结构编码

2.3 适值计算

离散型工厂选址问题的适值函数为 min ⁡ f = ∑ i = 1 m ∑ j n c i j x i j + ∑ i = 1 m d i y i \begin{array}{cl}{\min f=\sum\limits_{i=1}^{m} \sum\limits_{j}^{n} c_{i j} x_{i j}+\sum\limits_{i=1}^{m} d_{i} y_{i}} \end{array} minf=i=1mjncijxij+i=1mdiyi,可以将适值函数看成两个部分组成,分别是 ∑ i = 1 m ∑ j n c i j x i j \sum\limits_{i=1}^{m} \sum\limits_{j}^{n} c_{i j} x_{i j} i=1mjncijxij(运输成本), ∑ i = 1 m d i y i \sum\limits_{i=1}^{m} d_{i} y_{i} i=1mdiyi(固定成本)。对于一个染色体而言,由于 y i y_{i} yi的值是确定的,而且 d i d_{i} di是已知的,所以固定成本可以直接算出来,那么可以将适值函数简化为 min ⁡ f = ∑ i = 1 m ∑ j n c i j x i j + M \begin{array}{cl}{\min f=\sum\limits_{i=1}^{m} \sum\limits_{j}^{n} c_{i j} x_{i j}+M}\end{array} minf=i=1mjncijxij+M,其中 M = ∑ i = 1 m d i y i M=\sum\limits_{i=1}^{m} d_{i} y_{i} M=i=1mdiyi,因此可以应用产大于销的运输问题模型求出 x i j x_{ij} xij的值,利用式(1)可以求出目标函数 f f f的值。由于适值是群体中个体生存机会选择的唯一确定性指标,所以适值函数的形式直接决定着群体的进化行为。为了直接将适值函数与群体中的个体优劣度量相联系,在遗传算法中适值规定为非负,并且在任何情况下总是越大越好。对于本节讨论的选址问题所建立的目标函数,式(1)是求最小值,因此,令适值函数的倒数,即可求出该染色体的适值。

2.4 选择操作

​ 采用最优方式实现选择操作,即种群中适值最大的个体直接遗传到下一代,并把进化到目前为止最好的个体代替当代产生的最差个体直接复制到下一代,其余个体按照轮盘赌选择方法产生子代。

轮盘赌选择

​ 又称比例选择方法.其基本思想是:各个个体被选中的概率与其适应度大小成正比。
具体操作如下:

  1. 计算出群体中每个个体的适应度f(i=1,2,…,M),M为群体大小;
  2. 计算出每个个体被遗传到下一代群体中的概率;

P ( x i ) = f ( x i ) ∑ j = 1 N f ( x j ) P\left(x_{i}\right)=\frac{f\left(x_{i}\right)}{\sum\limits_{j=1}^{N} f\left(x_{j}\right)} P(xi)=j=1Nf(xj)f(xi)

3.计算出每个个体的累积概率;
q i = ∑ j = 1 i P ( x j ) q_{i}=\sum_{j=1}^{i} P\left(x_{j}\right) qi=j=1iP(xj)
q i q_{i} qi称为染色体 X [ i ] , i = 1 , 2 , . . . , n X[i],i=1,2,...,n X[i],i=1,2,...,n的积累概率)

4.在[0,1]区间内产生一个均匀分布的伪随机数 r r r;​
5.若 r &lt; q [ 1 ] r&lt;q[1] r<q[1],则选择个体1,否则,选择个体 k k k,使得: q [ k − 1 ] &lt; r ⩽ q [ k ] q[k-1]&lt;r\leqslant q[k] q[k1]<rq[k]成立;
6.重夏(4)、(5)共M次

2.5 遗传操作

​ 遗传操作调用了Python的遗传算法 g e a t p y geatpy geatpy的库

交叉

​ 对于交叉操作,采用通常的操作算子,产生新个体的上行附加码会出现重复。因此,采用部分映射交叉( P M X PMX PMX)算子。我们通过调用geatpy库的Xovpm函数来实现。图3为两个父代个体经 P M X PMX PMX操作产生两个子代个体的情况。
在这里插入图片描述

图3 二重结构编码的PMX

​ 需要说明的是,PMX操作只针对个体的上行附加码,子代个体的下行变量仍根据其父代个体中附加码与变量码的对应关系确定。

变异

​ 对于变异操作,采用逆位遗传算子。如图4所示,对父代个体随机选择两个变异点,两点间的上行附加码按相反顺序重新排列,而下行的变量码顺序则保持不变。
在这里插入图片描述

图4 逆位遗传变异

三、程序代码

import geatpy as ga  # 解遗传算法的库
from pymprog import *  # 解运输问题的库
import numpy as np
import xlrd


# -------------------解码函数---------------------------
def decode(Y, A, B, m):
    # step1
    List1 = np.multiply(np.array(Y), np.array(A))  # 计算 y*a

    sum1 = 0  # 再把他们累加起来
    for i in List1:
        sum1 += i

    sum2 = 0
    for j in B:
        sum2 += j

    # step2
    while sum1 < sum2:
        k = np.random.randint(0, m)
        if Y[k] == 0:
            sum1 += A[k]
            Y[k] = 1
        else:
            k = np.random.randint(1, m + 1)
            continue
    # else:

    # print("算法终止")

    return Y


# -----------------------适值函数-------------------------------
# 固定成本函数
def Fixed_cost(List2):
    fixed_cost = 0  # 再进行累加计算    计算建厂的固定成本
    for i in List2:
        fixed_cost += i
    return fixed_cost


# 运输成本函数
def report(Y_decode, A, B):  # 返回(产地,销地):运价;产地:产量; 销地:销量
    # 把目标函数简化成产大于销的运输问题
    a = ("A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "A10")  # 工厂(产地)
    b = ("B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "B10",
         "B11", "B12", "B13", "B14", "B15", "B16", "B17", "B18", "B19", "B20", "B21")  # 需求地(销地)
    datas = dict()  # 定义一个空字典 (产地,销地):运价
    datac = dict()  # 定义一个空字典   产地:产量
    datax = dict()  # 定义一个空字典   销地:销量
    List3 = np.multiply(np.array(Y_decode), np.array(A))  # 计算 y*a    产量

    # (产地,销地):运价
    Data = xlrd.open_workbook('单位运输费用.xlsx')  # 读取Excel运价列表
    table = Data.sheets()[0]  # 读取Excel列表的sheet1
    for i in range(0, 10):  # 先从十行里面拿出一行来
        x = np.array(table.row_values(i))
        for j in range(0, 21):  # 再从21列中取一列
            data = x[j]
            datas[a[i], b[j]] = data  # (产地,销地):运价

    # 产地:产量
    y = List3

    for i in range(0, 10):
        datac[a[i]] = y[i]  # 产地:产量

    # 销地:销量
    for j in range(0, 21):
        datax[b[j]] = B[j]  # 销地:销量
    return (datas, datac, datax)


def Transport_cost(datas, datac, datax):
    a = ("A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "A10")  # 工厂(产地)
    b = ("B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "B10",
         "B11", "B12", "B13", "B14", "B15", "B16", "B17", "B18", "B19", "B20", "B21")  # 需求地(销地)
    # 开始模型计算
    X = np.zeros((10, 21))   # 生成10行21列的0矩阵
    cost = 0.0
    begin('Transport')
    x = var('x', datas.keys())  # 调运方案
    minimize(sum(datas[i, j] * x[i, j] for (i, j) in datas.keys()), 'Cost')  # 总运费最少
    for i in datac.keys():  # 产地产量约束
        sum(x[i, j] for j in datax.keys()) == datac[i]
    for j in datax.keys():  # 销地销量约束
        sum(x[i, j] for i in datac.keys()) == datax[j]
    solve()

    for (i, j) in datas.keys():
        # print('x[i, j].primal',x[i, j].primal)
        if x[i, j].primal > 0 and datas[i, j] != 0:
            # print("产地:%s -> 销地:%s 运输量:%-2d 运价:%2d" % (i, j, int(x[i, j].primal), int(datas[i, j])))
            X[a.index(i)][b.index(j)] = int(x[i, j].primal)
    cost = int(vobj())
    # print("X", X)
    # print("总费用:%d" % int(vobj()))
    end()
    return (X, cost)


# -----------------------主函数开始-------------------------------------
def main():
    # 需求点的需求量
    B = [6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0]

    # 工厂容量(生产能力)
    A = [30, 40, 50, 55, 45, 48, 36, 50, 60, 35]

    # 各待选工厂的固定费用
    D = [65, 50, 40, 30, 20, 50, 45, 30, 35, 25]

    # 从待选工厂到需求点的单位运输费用
    Data = xlrd.open_workbook('单位运输费用.xlsx')
    table = Data.sheets()[0]

    Y = []  # 定义变量码
    Y_decode = []  # 定义解码生成的变量码
    m = 10  # 工厂个数
    T = 100  # 迭代次数
    decode_after_chrom2 = np.zeros((60, 10))    # 存储60条Y_decode
    datas = dict()  # 定义一个空字典 (产地,销地):运价
    datac = dict()  # 定义一个空字典   产地:产量
    datax = dict()  # 定义一个空字典   销地:销量
    fixed_cost = 0.0  # 初始固定成本
    X = np.zeros((10, 21))  # 运量矩阵
    transport_cost = 0.0  # 初始运输费用
    cost = 0.0  # 初始总费用

    best_y = np.zeros((1, 10))  # 所有代中的最优选址方案
    min_t = 0  # 最优的方案出现的代数
    all_min_cost = 1000  # 所有代中最小总费用
    all_min_X = np.zeros((10, 21))  # 所有代中最小总费用的运量矩阵
    FitnV = np.zeros((1, 60))  # 适应度列表
    NewChrlx = []  # 轮盘赌存储位置
    New_chrom1 = np.zeros((60, 10))
    New_chrom2 = np.zeros((60, 10))

    # ---------------------遗传编码---------------------------

    # 生成附加码
    chrom1 = ga.crtpp(60, 10, 10)   # 种群大小,染色体长度,种群最大元素
    print(chrom1)

    # 生成变量码
    FieldDR = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                        [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])
    chrom2 = ga.crtip(60, FieldDR)   # 种群大小,上界下界区域描述器
    print(chrom2)
    add_code = np.zeros((1, 10))  # 定义父代单行附加码
    new_add_code = np.zeros((1, 10))  # 定义子代单行附加码
    variable_code = np.zeros((1, 10))  # 定义父代单行变量码
    new_variable_code = np.zeros((1, 10))  # 定义子代单行变量码
    index_v = 0  # 定义初始索引值
    begin_New_chrom2 = np.zeros((60, 10))  # 定义经过交叉后的新的变量码种群
    again_New_chrom1 = np.zeros((60, 10))  # 经过变异后的附加码种群
    # tem_list = []
    a = 0
    for t in np.arange(0, T):
        min_cost = 1000  # 初始最小总费用
        min_X = np.zeros((10, 21))  # 初始最小总费用的运量矩阵
        min_i = 400  # 每一代中最小的运价在种群对应的位置
        better_y = np.zeros((1, 10))  # 每一代中的最有选址方案
        print("==========================第%d代种群======================" % t)

        for i in np.arange(0, 60):
            # print("第%d个染色体" % i)
            Y = chrom2[i]
            # print("-------------%d-----------------" % i)
            # print("Y",Y)
            Y_decode = np.array(decode(Y, A, B, m))
            decode_after_chrom2[i] = Y_decode
            List2 = np.multiply(np.array(D), np.array(Y_decode))  # 计算 d*y
            fixed_cost = Fixed_cost(List2)
            print("fixed_cost", fixed_cost)
            (datas, datac, datax) = report(Y_decode, A, B)
            (X, transport_cost) = Transport_cost(datas, datac, datax)
            cost = fixed_cost + transport_cost
            print('第%d个染色体的cost' % i, cost)
            FitnV[0][i] = 1 / cost
            if cost < min_cost:
                min_cost = cost
                min_X = X
                min_i = i
                better_y = Y_decode
            # print("第%d代种群中最小的cost"%t, min_cost)
            # print("最优运输方案", min_X)
            # print('对应的位置', min_i)
        NewChrlx = ga.rws(np.array(FitnV).T, 59)  # 轮盘赌
        # print(NewChrlx)
        for i in NewChrlx:
            New_chrom1[i] = chrom1[i]
            New_chrom2[i] = decode_after_chrom2[i]
            for j in range(0, 60):  # 把最大的适值得到染色体拿到新的种群中
                if j not in NewChrlx:
                    New_chrom1[j] = chrom1[j]
                    New_chrom2[j] = decode_after_chrom2[j]

        # 遗传操作
        Pc = 0.6  # 交叉概率
        Pm = 0.1  # 变异概率
        New_chrom1 = ga.xovpm(New_chrom1, 0.6)
        # print("交叉后的附加码New_chrom1",New_chrom1)
        # print("chrom1",chrom1)
        for change_1 in np.arange(0, 60):
            # print('------------修改chrom2第%d次-----------'%change_1)
            new_add_code = New_chrom1[change_1]
            add_code = chrom1[change_1]
            # print(type(add_code))
            variable_code = New_chrom2[change_1]
            for change_2 in np.arange(0, 10):
                index_v = add_code.tolist().index(new_add_code[change_2])
                # print("index_v",index_v)
                new_variable_code[0, change_2] = variable_code[index_v]
            begin_New_chrom2[change_1] = new_variable_code
            # print("begin_New_chrom2[change_1]",begin_New_chrom2[change_1])
            new_variable_code = np.zeros((1, 10))
        # print("交叉后的变量码begin_New_chrom2",begin_New_chrom2)
        # 变异操作
        ret = np.random.random()
        if ret > Pm:
            for mutation_v in np.arange(0, 60):
                new_add_code = New_chrom1[mutation_v]
                # print('未翻转的附加码new_add_code',new_add_code)
                random_1 = np.random.randint(0, 10)
                random_2 = np.random.randint(0, 10)
                a = np.abs(random_1 - random_2)
                tem_list = np.zeros(a + 1)
                if a != 0:
                    if random_2 > random_1:
                        for i, k in zip(np.arange(0, np.abs(random_2 - random_1) + 1), np.arange(random_1, random_2 + 1)):
                            tem_list[i] = new_add_code[k]
                        # print("未翻转的单行tem_list",tem_list)
                        # print("未翻转的tem_list类型",type(tem_list))
                        tem_list = tem_list.tolist()
                        # print("转换为列表的tem_list", tem_list)
                        tem_list.reverse()
                        # print("翻转后的tem_list",tem_list)
                        for i, k in zip(np.arange(0, np.abs(random_2 - random_1) + 1).tolist(),
                                        np.arange(random_1, random_2 + 1).tolist()):
                            new_add_code[k] = tem_list[i]
                        # print("翻转后的附加码",new_add_code)
                        again_New_chrom1[mutation_v] = new_add_code

                    else:
                        for i, k in zip(np.arange(0, np.abs(random_2 - random_1) + 1), np.arange(random_2, random_1 + 1)):
                            tem_list[i] = new_add_code[k]
                            # print("未翻转的单行tem_list",tem_list)
                        # print("未翻转的tem_list类型",type(tem_list))
                        tem_list = tem_list.tolist()
                        # print("转换为列表的tem_list",tem_list)
                        tem_list.reverse()
                        # print("tem_list",tem_list)
                        for i, k in zip(np.arange(0, np.abs(random_2 - random_1) + 1).tolist(),
                                        np.arange(random_2, random_1 + 1).tolist()):
                            new_add_code[k] = tem_list[i]
                        again_New_chrom1[mutation_v] = new_add_code
                    # print("循环中的again_New_chrom1", again_New_chrom1)
                else:
                    again_New_chrom1[mutation_v] = new_add_code
                    # print("else循环中的again_New_chrom1", again_New_chrom1)
        # print("New_chrom1",New_chrom1)
        # print('变异后的附加码again_New_chrom1',again_New_chrom1)
        chrom1 = again_New_chrom1
        chrom2 = begin_New_chrom2
        print('遗传操作后的chrom2', chrom2)
        print("第%d代种群中最小的cost" % t, min_cost)
        print("最优运输方案", min_X)
        print('对应的位置', min_i)
        if all_min_cost > min_cost:
            all_min_cost = min_cost
            all_min_X = min_X
            best_y = better_y
            min_t = t
    # New_chrom1[60]= chrom1[min_i]
    # New_chrom2[60] = decode_after_chrom2[min_i]
    # print("FitnV",np.array(FitnV).T.shape)
    print("所有代中种群中最小的cost", all_min_cost)
    print("所有代中的最优运输方案", all_min_X)
    print("最优的选址方案", best_y)
    print("最优的选址方案出现在第%d代" % min_t)


if __name__ == "__main__":
    main()

四、算例

有10个待选厂址向20个需求点提供产品,待选工厂的容量、需求点的需求量以及从待选工厂到需求点的单位运输费用如表1所示。由于所处的条件不同,各待选工厂的固定费用分别为65、50、40、30、20、50、45、30、35、25个单位。该问题的遗传算法参数设置为:交叉概率 p c p_{c} pc=0.6;变异概率 p m p_{m} pm=0.1;种群数量为60;进化代数为100;问如何选择工厂设置使所需的总费用最低?

表1 工厂选址有关数据
需求点工厂需求量
1109645378216
29.12.18.14.15.110.17.13.11.16.16
38.22.27.210.25.26.23.28.29.24.26
45.32.38.34.31.36.37.33.39.310.36
56.410.43.47.45.41.44.48.49.42.46
63.52.51.510.59.56.57.58.55.54.56
79.62.63.64.68.66.67.65.61.610.66
87.72.79.74.75.76.71.78.73.710.76
98.82.81.84.85.86.87.81.89.810.86
103.97.93.94.95.96.92.98.99.910.96
11529416783106
128.210.13.16.15.14.17.11.19.12.16
132.11.23.28.25.26.27.24.29.210.26
146.32.39.34.35.31.310.38.33.37.36
158.47.410.49.45.46.42.41.44.43.46
169.52.58.54.510.56.57.53.51.55.56
177.62.68.65.69.66.61.63.64.610.66
184.72.76.71.79.710.77.78.75.73.76
199.82.83.84.85.86.87.88.81.810.86
2010.92.97.94.95.96.93.98.99.91.96
生产能力30405055454836506035
初始附加码[[ 7.  1.  4. 10.  5.  8.  2.  9.  6.  3.]
         [10.  5.  3.  8.  1.  9.  6.  2.  7.  4.]
         [10.  6.  1.  8.  5.  3.  4.  7.  9.  2.]
         [ 3.  2.  8.  9.  4. 10.  7.  5.  6.  1.]
         [10.  8.  9.  5.  3.  2.  4.  6.  1.  7.]
         [ 8.  6.  5.  7.  4.  1.  3.  9.  2. 10.]
         [ 4.  1.  9. 10.  5.  7.  6.  3.  8.  2.]
         [ 2.  9. 10.  5.  7.  8.  1.  6.  3.  4.]
         [ 4.  8.  6.  5.  9. 10.  2.  3.  1.  7.]
         [ 3.  1.  2. 10.  4.  7.  5.  8.  9.  6.]
         [ 5.  4.  8.  7. 10.  9.  1.  6.  2.  3.]
         [ 4.  2.  9. 10.  1.  5.  8.  3.  7.  6.]
         [ 9.  7.  2.  6.  1.  8.  3.  5. 10.  4.]
         [ 8.  2.  5.  3.  9.  6.  1.  4. 10.  7.]
         [ 9.  1.  6.  4.  8.  2.  5. 10.  7.  3.]
         [ 7.  8.  1.  5.  6.  9.  2.  3. 10.  4.]
         [ 2.  6.  4.  9.  7.  3.  1.  5. 10.  8.]
         [ 6. 10.  8.  4.  9.  7.  1.  2.  5.  3.]
         [ 7.  9. 10.  8.  1.  4.  6.  2.  3.  5.]
         [ 2.  5. 10.  3.  1.  8.  7.  4.  9.  6.]
         [ 4.  2.  8.  1.  6. 10.  7.  3.  5.  9.]
         [ 3.  9.  2.  6.  1. 10.  8.  5.  7.  4.]
         [10.  1.  9.  3.  7.  8.  6.  4.  5.  2.]
         [ 6.  4.  5.  8.  7.  3.  2.  9. 10.  1.]
         [ 6. 10.  4.  2.  9.  1.  3.  8.  5.  7.]
         [ 7.  8.  1.  4.  9.  5.  3.  6.  2. 10.]
         [ 2.  8.  6.  7.  9.  3.  5.  4.  1. 10.]
         [ 4.  2.  3.  7.  9.  8.  1.  5.  6. 10.]
         [ 3.  9.  8. 10.  5.  2.  6.  1.  4.  7.]
         [ 1.  4.  5.  8.  7.  2. 10.  6.  3.  9.]
         [ 3.  5.  8.  4.  9. 10.  2.  1.  6.  7.]
         [ 7.  1. 10.  9.  3.  6.  5.  2.  4.  8.]
         [10.  7.  1.  4.  6.  3.  9.  2.  5.  8.]
         [ 1.  8.  3.  4. 10.  7.  6.  2.  9.  5.]
         [ 9.  3.  6.  5.  7.  1. 10.  4.  2.  8.]
         [ 6.  2.  4.  5.  7.  1.  3. 10.  9.  8.]
         [ 8.  1.  5.  2.  7. 10.  6.  4.  3.  9.]
         [ 2.  8.  9.  6.  4.  1.  5.  3.  7. 10.]
         [ 5. 10.  6.  9.  7.  3.  2.  1.  4.  8.]
         [ 7.  9.  6. 10.  1.  3.  2.  5.  8.  4.]
         [ 8.  4. 10.  3.  1.  7.  6.  5.  9.  2.]
         [ 6.  8.  3.  2.  5.  4. 10.  1.  9.  7.]
         [ 2.  5.  3.  7.  9.  8.  4. 10.  6.  1.]
         [ 3.  4.  6. 10.  1.  2.  8.  7.  9.  5.]
         [10.  2.  8.  5.  9.  3.  6.  4.  7.  1.]
         [10.  2.  3.  9.  5.  6.  8.  1.  7.  4.]
         [ 5.  7.  1.  2.  3.  6.  9.  8. 10.  4.]
         [10.  5.  7.  1.  3.  2.  8.  4.  9.  6.]
         [ 4.  8.  6.  2.  1.  9.  5. 10.  7.  3.]
         [ 3.  8.  5.  7.  1.  9.  4.  6. 10.  2.]
         [ 5.  6.  8.  1. 10.  9.  3.  7.  2.  4.]
         [ 6. 10.  2.  3.  7.  5.  9.  1.  8.  4.]
         [ 4.  2.  8.  3. 10.  7.  9.  1.  5.  6.]
         [ 3. 10.  1.  7.  5.  9.  2.  4.  8.  6.]
         [ 4. 10.  2.  1.  3.  5.  8.  7.  6.  9.]
         [ 7.  1.  5.  4.  6.  9. 10.  8.  2.  3.]
         [ 5.  3. 10.  8.  4.  2.  6.  1.  7.  9.]
         [ 3.  1.  7.  9.  8.  5.  6. 10.  2.  4.]
         [ 1.  9.  4.  2.  8. 10.  3.  5.  6.  7.]
         [ 9.  7.  5.  6.  4.  1.  8.  2. 10.  3.]]
初始变量码[[0 0 1 1 1 1 1 0 1 0]
         [1 1 0 0 0 1 1 0 1 1]
         [1 0 0 0 0 0 1 1 1 0]
         [0 0 0 0 0 1 1 1 1 1]
         [0 0 0 1 0 1 1 0 0 1]
         [0 0 0 0 1 0 1 0 1 1]
         [1 1 1 0 1 0 1 0 0 1]
         [1 0 1 0 1 0 0 0 0 1]
         [1 1 1 1 0 0 0 0 1 0]
         [1 0 1 0 1 0 0 1 1 1]
         [1 0 0 0 0 0 0 0 1 0]
         [0 0 0 0 1 0 0 0 1 1]
         [1 0 1 0 1 0 1 0 0 1]
         [1 1 1 1 0 0 1 1 0 0]
         [0 0 1 0 1 1 0 1 1 0]
         [1 1 1 0 1 0 0 0 1 0]
         [0 0 1 0 0 0 1 0 1 0]
         [1 0 0 1 0 1 0 0 0 1]
         [1 0 1 1 0 1 1 1 1 1]
         [0 0 1 0 0 0 0 0 0 1]
         [1 0 1 0 1 0 1 1 0 1]
         [0 0 1 0 0 0 1 0 1 0]
         [0 1 1 0 0 0 0 0 0 1]
         [0 1 0 0 1 0 0 0 0 1]
         [0 1 1 1 0 0 0 1 1 0]
         [0 0 0 1 0 1 0 1 0 0]
         [1 1 0 0 1 1 0 1 1 0]
         [1 1 0 0 1 1 1 1 0 0]
         [0 1 1 1 1 1 1 1 1 1]
         [1 1 0 0 0 1 0 0 1 1]
         [0 0 1 0 1 1 0 0 0 1]
         [0 1 0 0 0 1 0 0 0 0]
         [0 1 1 1 0 0 1 0 1 1]
         [0 0 0 1 1 1 1 1 1 1]
         [0 1 0 0 1 1 0 1 1 0]
         [0 1 1 0 1 1 0 1 1 0]
         [1 1 0 0 1 1 0 0 0 1]
         [0 1 0 0 0 1 0 1 1 1]
         [0 1 1 0 0 0 0 0 1 0]
         [1 0 0 0 1 0 0 0 0 1]
         [1 1 0 0 0 1 1 0 1 1]
         [0 1 0 1 0 0 0 1 1 1]
         [1 0 1 0 0 1 1 0 0 0]
         [0 0 1 0 1 0 0 0 0 0]
         [1 1 1 1 0 0 0 1 1 1]
         [0 0 0 1 0 0 1 0 0 1]
         [1 1 1 1 0 1 1 1 0 1]
         [1 1 1 0 1 1 1 1 0 0]
         [1 0 1 1 1 1 0 0 0 1]
         [0 0 1 1 1 1 0 0 1 0]
         [0 0 1 1 0 0 0 0 0 0]
         [1 1 1 0 0 0 1 1 1 1]
         [1 1 1 0 1 0 1 1 1 0]
         [1 1 0 1 1 1 0 1 0 1]
         [1 1 1 1 0 0 0 0 1 0]
         [0 1 1 1 0 1 1 0 1 0]
         [0 0 0 0 0 0 1 0 1 1]
         [1 1 1 1 0 1 1 0 1 1]
         [0 0 0 0 1 1 1 0 0 1]
         [1 0 1 0 1 1 0 1 0 0]]
所有代中的最优运输方案 [[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
                    [0. 0. 4. 0. 0. 6. 6. 0. 0. 0. 0. 0. 6. 0. 0. 6. 6. 0. 6. 0. 0.]
                    [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
                    [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
                    [0. 6. 2. 6. 0. 0. 0. 6. 6. 6. 6. 0. 0. 6. 1. 0. 0. 0. 0. 0. 0.]
                    [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
                    [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
                    [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
                    [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
                    [6. 0. 0. 0. 6. 0. 0. 0. 0. 0. 0. 6. 0. 0. 5. 0. 0. 6. 0. 6. 0.]]
最优的选址方案出现在第13代
所有代中种群中最小的cost 468.0
最优的选址方案 [0. 1. 0. 0. 1. 0. 0. 0. 0. 1.]
使用遗传方法进行计算可得优化设置工厂为 2,5,10
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页