钢管订购和运输模型——Python实现

haohai9309 / 2023-05-13 / 原文

要铺设一条\(A_1→A_2→…→A_{15}\)的输送天然气的主管道,如图所示。经筛选后可以生产这种主管道钢管的钢厂有\(S_1 ,S_2,…,S_7\)。图中粗线表示铁路,单细线表示公路,双细线表示要铺设的管道(假设沿管道或者原有公路,或者建有施工公路),圆圈表示火车站,每段铁路、公路和管道旁的阿拉伯数字表示里程(单位:km)。为方便计算, 1km主管道钢管称为1单位钢管。

一、问题描述

一个钢厂如果承担制造这种钢管,至少需要生产500个单位。钢厂\(S_i\) 在指定期限内能生产该钢管的最大数量为\(s_i\)个单位,钢管出厂销价1单位钢管为\(p_i\) 万元,如下表:

\(i\) 1 2 3 4 5 6 7
\(S_i\) 800 800 1000 2000 2000 2000 3000
\(p_i\) 160 155 155 160 155 150 160

单位钢管的铁路运价如下表:

里程(km) ≤300 301~350 351~400 401~450 451~500
运价(万元) 20 23 26 29 32
里程(km) 501~600 601~700 701~800 801~900 901~1000
运价(万元) 37 44 50 55 60

1000km以上每增加1至100km运价增加5万元。公路运输费用为1单位钢管每公里0.1万元(不足整公里部分按整公里计算)。钢管可由铁路、公路运往铺设地点(不只是运到点\(A_1,A_2,...,A_{15}\) ,而是管道全线)。请制定一个主管道钢管的订购和运输计划,使总费用最小(给出总费用)。

二、数学模型

2.1 模型假设

假设沿管道或者原来有公路,或者建有施工公路;
运费只按铁路、公路里程收取,即不考虑火车、汽车由于停靠站等其他一切外因带来的费用;
钢管在铺设过程中以1km为单位进行铺设;
钢管可由铁路、公路运往铺设路线任一地点;
所有钢管在指定期限内都能按时生产并运送指定地点;
钢管铺设过程中由站点向左右两边进行铺设。

2.2 符号说明

符号 解释
\(s_i\) \(i\)个钢厂的最大产量,\(i=1,2,...,7\)
\(A_j\) 输送管道(主管道)上的第\(j\)个点,\(j=1,2,...,15\)
\(c_{ij}\) 钢厂\(S_i\)向点\(A_j\)订购和运输单位钢管的费用,\(i=1,2,...,7 \quad j=1,2,...,15\)
\(x_{ij}\) 钢厂\(S_i\)向点\(A_j\)运输的钢管量,\(i=1,2,...,7 \quad j=1,2,...,15\)
\(p_i\) \(i\)个钢厂1单位钢管的销价,\(i=1,2,...,7\)
\(y_j\) 在点\(A_j\)与点\(A_{j+1}\)之间的公路上,运输点\(A_j\)向点\(A_{j+1}\)方向铺设的钢管量,\(j=1,2,3,...,14\)
\(A_{ij}\) 1单位钢管从钢厂\(S_i\)到点\(A_j\)的最少总费用,即订购费用、公路运费、铁路运费、铺设管道和钢管销价之和,\(i=1,2,...,7 \quad j=1,2,...,15\)
\(l_j\) 管道第\(j\)需要铺设的钢管量,\(j=1,2,...,15\)
\(y_j\) 节点\(j\)向左铺设的钢管量,\(j=1,2,...,15\)
\(z_j\) 节点\(j\)向右铺设的钢管量,\(j=1,2,...,15\)

2.3 数学模型

\[\begin{array}{ll} \min \sum_{i=1}^7 \sum_{j=1}^{15} c_{i j} x_{i j}+\frac{0.1}{2} \sum_{j=1}^{15}\left[z_j\left(z_j+1\right)+y_j\left(y_j+1\right)\right] \\ \text { s.t. }\left\{\begin{array}{l} \sum_{j=1}^{15} x_{i j} \in\{0\} \cup\left[500, s_i\right], \quad i=1,2, \cdots, 7, \\ \sum_{j=1}^{15} x_{i j} \leq s_i, \quad i=1,2, \cdots, 7, \\ \sum_{i=1}^7 x_{i j}=z_j+y_j,\quad j=1,2, \cdots, 15, \\ y_{j+1}+z_j=l_j, \quad j=1,2, \cdots, 14, \\ y_1=0, \quad z_{15}=0 \\ x_{i j} \geqslant 0, z_j \geqslant 0, y_j \geqslant 0,\quad i=1,2, \cdots 7, j=1,2 \cdots, 15 \end{array}\right. \end{array} \]

三、计算过程

使用计算机求解上述数学规划时, 需要对非线性约束条件进行处理。引进0-1变量

\[f_i=\left\{\begin{array}{l} 1, \text { 钢厂 } i \text { 生产, } \\ 0, \text { 钢厂 } i \text { 不生产} \end{array} \quad \quad i=1,2, \cdots, 7\right. \]

把约束条件第一式转化为线性约束

\[500 f_i \leqslant \sum_{j=1}^{15} x_{i j} \leqslant s_i f_i,\quad i=1,2, \cdots, 7 \]

3.1 运费矩阵的计算

下面介绍购买单位钢管及从\(S_i(i=1 ,2,…,7)\)运送到\(A_j(j = 1 ,2,…,15)\)的最小购运费用的计算过程。
计算铁路任意两点间的最小运输费用
  由于铁路运费不是连续的,故不能直接构造铁路费用赋权图,用Floyd算法来计算任意两点间的最小运输费用。但可以首先构造铁路距离赋权图,用Floyd算法来计算任意两点间的最短铁路距离值,再依据题中的铁路运价表,求出任意两点间的最小铁路运输费用。这就可以巧妙地避开铁路运费不是连续的问题。
首先构造铁路距离赋权图\(G=(V,E_1,W_1)\),其中\(V = \{S_1,…,S_7,A_1, ,…,A_{15} ,B_1,,…,B_{17}\}\)
各顶点的编号如上图所示,

\[W_1=[w_{ij}^{(1)}]_{39 \times 39} \]

,有

\[w_{ij}^{(1)}=\left\{\begin{array}{l} d_{ij}^{(1)}, i和j之间有铁路直接相连 \\ +\infin, i和j之间没有铁路直接相连 \end{array} \quad \quad \quad i,j=1,2, \cdots, 15\right. \]

\(d_{ij}^{(1)}\) 表示两点\(i,j\)之间的铁路距离,然后应用Floyd算法求得任意两点间的最短铁路距离。
根据铁路运价表,可以得到铁路费用赋权完全图\(G1= (V,E_1,W_1)\),其中\([c_{ij}^{(1)}]_{39 \times 39}\),这里\(c_{ij}\)为第\(i,j\)顶点间的最小铁路运输费用,若两点间的铁路距离值为无穷大,则对应的铁路运输费用也为无穷大。

构造公路费用的赋权图
构造公路费用赋权图\(G2=( V,E_2, W_2)\),其中\(V\)同上,\(d_{ij}^{(2)}\)\(i,j\)之间的公路距离。

\[W_2=[c_{ij}^{(2)}]_{39 \times 39} \]

,有

\[c_{ij}^{(2)}=\left\{\begin{array}{l} 0.1d_{ij}^{(2)}, i和j之间有公路直接相连 \\ +\infin, i和j之间没有公路直接相连 \end{array} \quad \quad \quad i,j=1,2, \cdots, 15\right. \]

计算任意两点间的最小运输费用
由于可以用铁路、公路交叉运送,所以任意相邻两点间的最小运输费用为铁路、公路两者最小运输费用的最小值。构造铁路公路的混合赋权图\(G=(V,E,W),W=[c_{ij}^{(3)}]_{39 \times 39}\),其中\(c_{ij}^{(3)}=\min(c_{ij}^{(1)},c_{ij}^{(2)})\),对图\(G\)应用Floyd算法,就可以计算出所有顶点对之间的最小运输费用,最后提取需要的\(S_i(i=1 ,2,…,7)\)\(A_j(j=1,2,…,15)\)的最小运送费用C,(单位:万元),如下表所列。

单位钢管从钢厂\(S_i\)运输到\(A_j\)的运输费用

\(A_1\) \(A_2\) \(A_3\) \(A_4\) \(A_5\) \(A_6\) \(A_7\) \(A_8\) \(A_9\) \(A_{10}\) \(A_{11}\) \(A_{12}\) \(A_{13}\) \(A_{14}\) \(A_{15}\)
S(1) 170.7 160.3 140.2 98.6 38 20.5 3.1 21.2 64.2 92 96 106 121.2 128 142
S(2) 215.7 205.3 190.2 171.6 111 95.5 86 71.2 114.2 142 146 156 171.2 178 192
S(3) 230.7 220.3 200.2 181.6 121 105.5 96 86.2 48.2 82 86 96 111.2 118 132
S(4) 260.7 250.3 235.2 216.6 156 140.5 131 116.2 84.2 62 51 61 76.2 83 97
S(5) 255.7 245.3 225.2 206.6 146 130.5 121 111.2 79.2 57 33 51 71.2 73 87
S(6) 265.7 255.3 235.2 216.6 156 140.5 131 121.2 84.2 62 51 45 26.2 11 28
S(7) 275.7 265.3 245.2 226.6 166 150.5 141 131.2 99.2 77 66 56 38.2 26 2

3.2 总费用的计算

**单位钢管从钢厂\(S_i\)运输到\(A_j\)的运输量 **

\(A_1\) \(A_2\) \(A_3\) \(A_4\) \(A_5\) \(A_6\) \(A_7\) \(A_8\) \(A_9\) \(A_{10}\) \(A_{11}\) \(A_{12}\) \(A_{13}\) \(A_{14}\) \(A_{15}\) 总量
S(1) 0 0 0 335 0 200 265 0 0 0 0 0 0 0 0 800
S(2) 0 179 188 133 0 0 0 300 0 0 0 0 0 0 0 800
S(3) 0 0 320 0 16 0 0 0 664 0 0 0 0 0 0 1000
S(4) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
S(5) 0 0 0 0 600 0 0 0 0 0 415 0 0 0 0 1015
S(6) 0 0 0 0 0 0 0 0 0 351 0 86 333 621 165 1556
S(7) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

即厂家\(S_1\)\(A_4\)节点运输335单位钢管,往\(A_6\)节点运输200单位钢管,往\(A_7\)节点运输265单位钢管,共计800单位。其它钢厂以此类推…………最小费用为127.8632亿元。

3.3 Python计算代码

#铁路赋权图


#公路赋权图


#最小费用


#运输量的计算
s=[800 800 1000 2000 2000 2000 3000];
path=zeros(39,39);
path1=zeros(39,39);
path2=zeros(39,39);
cf=zeros(7,15);
w=zeros(39,39);c=zeros(39,39);c2=zeros(39,39);
w(1,29)=20;w(1,30)=202;w(2,30)=1200;w(3,31)=690;w(4,34)=690;w(5,33)=462;
w(6,38)=70;w(7,39)=30;w(23,25)=450;w(24,25)=80;w(25,27)=1150;
w(26,28)=306;w(27,30)=1100;w(28,29)=195;w(30,31)=720;w(31,32)=520;
w(32,34)=170;w(33,34)=88;w(34,36)=160;w(35,36)=70;w(36,37)=320;
w(37,38)=160;w(38,39)=290;
w=w+w';
for i=1:39
    for j=1:39
        if(i~=j)&& w(i,j)==0
            w(i,j)=200000000;
        end
    end
end
for k=1:39
    for i=1:39
        for j=1:39
            if w(i,j)>w(i,k)+w(k,j)
                w(i,j)=w(i,k)+w(k,j);
                path(i,j)=k;
            end
        end
    end
end
c1=w;
for i=1:39
    for j=1:39
        if c1(i,j)==0 
            c1(i,j)=0;
        end
        if c1(i,j)>0 && c1(i,j)<=300
            c1(i,j)=20;
        end
        if c1(i,j)>300 && c1(i,j)<=350
            c1(i,j)=23;
        end
        if c1(i,j)>350 && c1(i,j)<=400
            c1(i,j)=26;
        end
        if c1(i,j)>400 && c1(i,j)<=450
            c1(i,j)=29;
        end
        if c1(i,j)>450 && c1(i,j)<=500
            c1(i,j)=32;
        end
        if c1(i,j)>500 && c1(i,j)<=600
            c1(i,j)=37;
        end
        if c1(i,j)>600 && c1(i,j)<=700
            c1(i,j)=44;
        end
        if c1(i,j)>700 && c1(i,j)<=800
            c1(i,j)=50;
        end
        if c1(i,j)>800 && c1(i,j)<=900
            c1(i,j)=55;
        end
        if c1(i,j)>900 && c1(i,j)<=1000
            c1(i,j)=60;
        end
        if c1(i,j)>1000 && rem(c1(i,j),100)==0
            c1(i,j)=(floor((c1(i,j)-1000)/100))*5+60;
        end
        if c1(i,j)>1000 && rem(c1(i,j),100)~=0
            c1(i,j)=(floor((c1(i,j)-1000)/100))*5+65;
        end
    end
end
c2(1,14)=31;c2(6,21)=110;c2(7,22)=20;c2(8,9)=104;c2(9,10)=301;c2(9,23)=3;
c2(10,11)=750;c2(10,24)=2;c2(11,12)=606;c2(11,27)=600;c2(12,13)=194;
c2(12,26)=10;c2(13,14)=205;c2(13,28)=5;c2(14,15)=201;c2(14,29)=10;
c2(15,16)=680;c2(15,30)=12;c2(16,17)=480;c2(16,31)=42;c2(17,18)=300;
c2(17,32)=70;c2(18,19)=220;c2(18,33)=10;c2(19,20)=210;c2(19,35)=10;
c2(20,21)=420;c2(20,37)=62;c2(21,22)=500;c2(21,38)=30;c2(22,39)=20;
c2=c2+c2';
for i=1:39
    for j=1:39
        if(i~=j)&&c2(i,j)==0
            c2(i,j)=200000000;
        end
    end
end
for k=1:39
    for i=1:39
        for j=1:39
            if c2(i,j)>c2(i,k)+c2(k,j)
                c2(i,j)=c2(i,k)+c2(k,j);
                path1(i,j)=k;
            end
        end
    end
end
c3=c2;
c2=0.1*c2;
for i=1:39
    for j=1:39
        if c1(i,j)<c2(i,j)
            c(i,j)=c1(i,j);
        end
        if c1(i,j)>c2(i,j)
            c(i,j)=c2(i,j);
        end
        if c1(i,j)==c2(i,j)
            c(i,j)=c2(i,j);
        end
    end
end
for i=1:39
    for j=1:39
        for k=1:39
            if c(i,j)>c(i,k)+c(k,j)
                c(i,j)=c(i,k)+c(k,j);
                path2(i,j)=k;
            end
        end
    end
end
for i=1:39
    for j=1:39
        if (i<=7)&&(j>=8)&&(j<=22)
            cf(i,j-7)=c(i,j);
        end
    end
end
% xlswrite('F:\第三道问题:钢管运输问题\钢管运输问题1.xlsx',cf,'sheet1','b3:p9');
% xlswrite('F:\第三道问题:钢管运输问题\钢管运输问题1.xlsx',w,'sheet2','b4:AN42');
% xlswrite('F:\第三道问题:钢管运输问题\钢管运输问题1.xlsx',c1,'sheet2','b54:AN92');
% xlswrite('F:\第三道问题:钢管运输问题\钢管运输问题1.xlsx',c3,'sheet3','b4:AN42');
% xlswrite('F:\第三道问题:钢管运输问题\钢管运输问题1.xlsx',c2,'sheet3','b54:AN92');
% xlswrite('F:\第三道问题:钢管运输问题\钢管运输问题1.xlsx',c,'sheet4','b4:AN42');

使用计算机求解上述数学规划时,需要对约束条件(20)进行处理。我们引进0 −1 变量,求得总费用的最小值为 127.8632 亿。

参考文献

  1. 钢管订购与运输优化模型
  2. 钢管运输模型
  3. 最短路+最小费用+线性规划(钢管订购和运输问题)