最短路+最小费用+线性规划(钢管订购和运输问题)

本文详细解析了如何通过Floyd算法计算铁路与公路运输费用,利用0-1规划解决钢管从钢厂到管道节点的最优订购与运输问题。通过实例展示,找到最小运费并确定钢管量,最终实现127.8632亿元的最低成本解决方案。
摘要由CSDN通过智能技术生成

钢管订购和运输问题题目详情:

 分析:解决本题首先计算运输一单位钢管的费用(最短路),再根据题目的约束条件求得钢管量(0-1规划)。

符号说明:

 

1.求最小运费

(1)构造铁路任意两点间的最小运输费用赋权图

        首先用Floyd算法构造铁路距离赋权图,接着计算两点间最短铁路距离值,再根据题目给出的铁路运价表,得到任意两点间的最小铁路费用。构造铁路距离矩阵c1(matlab代码如下:)

%w为铁路距离矩阵,c1为铁路费用矩阵
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);%求最短路径

            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
        %当距离大于1000时,特别注意临界值!!!
        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

(2)构造铁路任意两点间的最小运输费用赋权图

        首先用Floyd算法构造公路距离赋权图,接着计算两点间最短公路距离值,再根据题目给出的公路运价表,得到任意两点间的最小公路费用。构造公路距离矩阵c2(matlab代码如下)

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);%求最短路径
            end
        end
    end
end
c3=c2;%公路距离矩阵
c2=0.1*c2;%求公路费用矩阵

(3)计算任意两点间的最小运输费用

        由于钢管可以用铁路和公路交叉运送,所以任意两点间的最小运输费用为铁路、公路两者最小运输费用的最小值,c=min{c1,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

     最终求得最小运费结果:

单位钢管从钢厂S(i)运输到A(I)的运输费用
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.7160.3140.298.63820.53.121.264.29296106121.2128142
S(2)215.7205.3190.2171.611195.58671.2114.2142146156171.2178192
S(3)230.7220.3200.2181.6121105.59686.248.2828696111.2118132
S(4)260.7250.3235.2216.6156140.5131116.284.262516176.28397
S(5)255.7245.3225.2206.6146130.5121111.279.257335171.27387
S(6)265.7255.3235.2216.6156140.5131121.284.262514526.21128
S(7)275.7265.3245.2226.6166150.5141131.299.277665638.2262

在得到最小运费后,利用0-1规划,求最小费用(运费+钢管费+铺设费)模型:

 

由此,我们可建立目标模型如下:(注:此处的c应为cf,cf=c+p)写错啦emmm……

 

约束条件:

根据该模型求解(lingo代码在文末)

最终求得钢管订购的数据如表:

单位钢管从钢厂S(i)运输到A(I)的运输量
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)000335020026500000000800
S(2)01791881330003000000000800
S(3)003200160006640000001000
S(4)0000000000000000
S(5)00006000000041500001015
S(6)0000000003510863336211651556
S(7)0000000000000000

即厂家S1往A4节点运输335单位钢管,往A6节点运输200单位钢管,往A7节点运输265单位钢管,共计800单位。其它钢厂以此类推…………最小费用为127.8632亿元。

总结:这道题目解题代码

代码1(matlab)

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');

代码2(Lingo)

model:
sets:
aa/1..7/:f,p,s;
bb/1..15/:l,r,a,b;
link(aa,bb):cf,x;
endsets
data:
p=160 155 155 160 155 150 160;
s=800 800 1000 2000 2000 2000 3000;
b=104 301 750 606 194 205 201 680 480 300 220 210 420 500 0;
!从文件中导出数据
cf=@ole('F:\第三道问题:钢管运输问题\钢管运输问题1.xlsx','data');!data为Excel表的数据,此处需提前在Excel表中设置
设置过程参考下方步骤
!写入文件  注:x,ll,rr需在Excel表中提前设置
@ole('F:\第三道问题:钢管运输问题\钢管运输问题1.xlsx','x')=x;
@ole('F:\第三道问题:钢管运输问题\钢管运输问题1.xlsx','ll')=l;
@ole('F:\第三道问题:钢管运输问题\钢管运输问题1.xlsx','rr')=r;
enddata
min=@sum(link(i,j):(cf(i,j)+p(i))*x(i,j))+0.05*@sum(bb(j):l(j)^2+l(j)+r(j)^2+r(j));
@for(aa(i):@sum(bb(j):x(i,j))>=500*f(i));
@for(aa(i):@sum(bb(j):x(i,j))<=s(i)*f(i));
@for(bb(j):@sum(aa(i):x(i,j))=l(j)+r(j));
@for(bb(j)|j#ne#15:r(j)+l(j+1)=b(j));
l(1)=0;r(15)=0;
@for(aa:@bin(f));
@for(bb:@gin(l));
end

PS:Lingo将Excel表中数据导出或将数据写入Excel表,需对Excel表提前设置单元格名称,设置步骤如下:

选定数据写入的合适区域,点击“公式”-“名称管理器”-“新建”名称,此时就可自定义名称啦

 

以下是使用Lingo求解最小费用最短路问题的代码: ```lingo model: sets: i /1*10/ j /1*10/ k /1*20/ parameters: c(i,j) / 1 2 3 2 4 1 3 4 2 5, 2 1 3 2 1 4 3 3 3 2, 2 3 1 4 2 5 1 2 4 3, 3 2 4 1 3 2 5 1 4 2, 4 1 2 3 1 4 2 3 2 3, 1 4 5 2 4 1 3 2 2 1, 3 3 1 5 2 3 1 4 3 2, 4 1 2 1 3 2 4 3 1 2, 2 2 4 4 2 1 3 2 2 3, 5 1 3 2 1 4 2 3 1 2 / f(i,j) / 10 30 20 40 60 10 20 10 30 50, 20 10 30 40 10 50 20 30 40 20, 30 20 10 50 40 60 10 30 20 40, 40 30 50 20 10 30 60 10 20 30, 50 10 20 30 20 10 40 30 30 20, 10 50 60 20 50 10 20 30 20 10, 20 40 30 10 30 20 50 20 40 30, 30 10 20 10 20 30 40 30 10 20, 10 20 50 40 30 10 20 30 20 20, 50 10 30 20 10 50 40 30 20 40 / start(i) /1/ end(i) /10/ variables: x(i,j) binary z equations: obj: z = sum((i,j), f(i,j)*x(i,j)) start_con: sum(j, x(start,j)) = 1 end_con: sum(i, x(i,end)) = 1 flow_con(i)$(not sameas(i,start) and not sameas(i,end)): sum(j, x(i,j)) - sum(j, x(j,i)) = 0 arc_con(i,j): x(i,j) + x(j,i) <= 1 subtour_con(k)$(card(k) gt 1): sum((i,j)$(ord(i) lt ord(j) and i in k and j in k), x(i,j)) <= card(k) - 1 model_name "MinCostShortestPath"; solve; display z, x; ``` 该模型中,`i`和`j`表示图的节点,`k`表示子集,`c(i,j)`表示节点i到节点j的距离,`f(i,j)`表示节点i到节点j的费用,`start(i)`表示起点,`end(i)`表示终点,`x(i,j)`表示是否选择从节点i到节点j的路径,`z`表示最小费用。模型的约束分别为:起点只有一条出边,终点只有一条入边,流量守恒约束,路径是有向无环图,子集约束,目标函数为最小费用
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值