运输问题中表上作业法实现

Step1:初始基可行解确定

方法1:西北角法

西北角法函数文件

function [B,X]=XiBeiJiao(demand,supply,cost)
    [m,n] = size(cost)
    B = zeros(m,n);X=zeros(m,n)
    B(1,1) = 1;
    i = 1,j = 1;
    while((i<=m)&&(j<=n))
        if  supply(i) < demand(j)
            X(i,j)=supply(i)
            demand(j) = demand(j)-supply(i)
            supply(i)=0 
            B(i,j) = 1 
            
            i = i + 1   
        else supply(i) > demand(j) 
            X(i,j)=demand(j)
            supply(i) = supply(i)-demand(j) 
            demand(j)=0 
            B(i,j) = 1
           
            j = j + 1     
        end
    end
    disp("初始基所在位置")
    disp(B)
    disp("初始调运方案")
    disp(X)
end

  

实例1运行代码

demand=[3;6;5;6]
supply=[7;4;9]
cost=[3,11,3,10;1,9,2,8;7,4,10,5]
XiBeiJiao(demand,supply,cost)

实例1运行结果

初始基所在位置
     1     1     0     0
     0     1     1     0
     0     0     1     1
​
初始调运方案
     3     4     0     0
     0     2     2     0
     0     0     3     6

实例2运行代码

clc;clear all
demand=[3;2;3;2]
supply=[5;2;3]
cost= [3 7 6 4;2 4 3 2;4 3 8 5]
XiBeiJiao(demand,supply,cost)

实例2运行结果

初始基所在位置
     1     1     1     0
     0     0     1     0
     0     0     1     1
​
初始调运方案
     3     2     0     0
     0     0     2     0
     0     0     1     2

方法2:最小元素法

最小元素法函数文件

function [B,X]=ZuiXiaoYuanSu(demand,supply,cost)
%本程序通过最小元素法求解运输问题的初始解
%B为初始基可行解所在位置,X为初始调运方案
   [m,n]=size(cost);I=[1:m];X=zeros(m,n);B=zeros(m,n);flag=0;
   while flag==0
        [row,col] = find(cost ==min(min(cost)))%寻找最小元素
        a =row(1,:);b=col(1,:) %防止最小元素有两个以上
        if  supply(a) < demand(b)
            demand(b) = demand(b) - supply(a);
            B(a,b) = 1;%记为基
            X(a,b) = supply(a);%进行调运
            supply(a) = 0;
            cost(a,:) = inf*ones(1,n)%删除此行
        elseif supply(a) > demand(b)
            supply(a) = supply(a) - demand(b);
            B(a,b) = 1;
            X(a,b) = demand(b);
            demand(b) = 0;cost(:,b) = inf*ones(m,1)%删除此列
        else supply(a) = demand(b)%退化情况
             B(a,b) = 1;
             X(a,b) = supply(a);
            supply(a)=0;demand(b)=0;
            cost(a,:)=inf*ones(1,n)
             cost(:,b)=inf*ones(m,1)
             %补0
             if length(find(B==1)) < m+n-2
                I1 =find(I~=a)
                B(I1(end),b)=1
             end         
        end  
        if length(find(B==1))==m+n-1
            flag=1
        else
            flag =0
        end  
    end
disp("初始基所在位置")
disp(B)
disp("初始调运方案")
disp(X)
end    

实例1运行代码

demand=[3;6;5;6]
supply=[7;4;9]
cost=[3,11,3,10;1,9,2,8;7,4,10,5]
ZuiXiaoYuanSu(demand,supply,cost)

实例1运行结果

初始基所在位置
     0     0     1     1
     1     0     1     0
     0     1     0     1
​
初始调运方案
     0     0     4     3
     3     0     1     0
     0     6     0     3

实例2运行代码

demand=[3;2;3;2]
supply=[5;2;3]
cost= [3 7 6 4;2 4 3 2;4 3 8 5]
ZuiXiaoYuanSu(demand,supply,cost)

 

实例2运行结果

初始基所在位置
     1     0     1     1
     1     0     0     0
     0     1     1     0
初始调运方案
     1     0     2     2
     2     0     0     0
     0     2     1     0

方法3:元素差额法

元素差额法函数文件

function [C,X]=vogel(demand,supply,cost)
%本程序通过元素差额法求解运输问题的初始解
%C为初始基可行解所在位置,X为初始调运方案
[m,n]=size(cost)
X=zeros(m,n);C=zeros(m,n);I=[1:m];flag=0;
while flag==0
    A=sort(cost,2,'ascend') 
    zd1=A(:,1)%行最小值
    cd1 = A(:,2)%行次小值
    h = cd1-zd1%行差额
    B=sort(cost,'ascend')
    zd2=B(1,:)';cd2=B(2,:)'
    l = cd2-zd2%列差额
    [z1,row]=max(h);[z2,col]=max(l);z=max([z1,z2])
    if z==z1
        [~,col]= min(cost(row,:))%此行中最小值,记录列数
    else z==z2
        [~,row] = min(cost(:,col))%此列中最小值,记录行数
    end        
    if demand(col)>supply(row)
       X(row,col)=supply(row);C(row,col)=1; 
       demand(col) = demand(col)-supply(row);supply(row) = 0;
       cost(row,:) = inf*ones(1,n)
    elseif demand(col)  
 

实例1运行代码

clc;clear all
demand=[3;6;5;6]
supply=[7;4;9]
cost=[3,11,3,10;1,9,2,8;7,4,10,5]
volger(demand,supply,cost)

实例1运行结果

初始基所在位置
     0     0     1     1
     1     0     0     1
     0     1     0     1
初始调运方案
     0     0     5     2
     3     0     0     1
     0     6     0     3

实例2运行代码

clc;clear all
demand=[3;2;3;2]
supply=[5;2;3]
cost= [3 7 6 4;2 4 3 2;4 3 8 5]
volger(demand,supply,cost)

实例2运行结果

初始基所在位置
     1     0     1     1
     0     0     1     0
     0     1     0     1
​
初始调运方案
     3     0     1     1
     0     0     2     0
     0     2     0     1

  

Step2:解的检验(位势法)

%利用位势法求解非基变量检验数
%此程序需要输入初始调运方案B
clc;clear all
demand=[3;6;5;6];supply=[7;4;9];cost=[3,11,3,10;1,9,2,8;7,4,10,5]
[m,n]=size(cost)
B=[0,0,3,10;1,0,2,0;0,4,0,5]
[BI,BJ]=find(B~=0)%记录基变量下标
b=zeros(m+n-1,1)
A=zeros(m+n-1,m+n)%初始化系数矩阵
%给初值
for i=1:m+n-1
    A(i,BI(i))=1
    A(i,BJ(i)+m)=1%生成系数矩阵 
end
A1=A(:,1:3);A2=A(:,4:end)
A=[1,0,0,0,0,0,0;A]
b = [0; cost(sub2ind([m,n],BI,BJ))];
x=A \ b
u = x(1:m);v = x(m+1:end);
[nI,nJ] = find(B==0); 
Sigma = zeros(m,n);               
for i=1:length(nI)
    Sigma(nI(i),nJ(i)) = cost(nI(i),nJ(i)) - (u(nI(i)) + v(nJ(i)));
end
disp("非基变量检验数")
disp(Sigma)

 输出结果

非基变量检验数
    1     2     0     0
    0     1     0    -1
   10     0    12     0

非基变量检验数存在负数情况,需要对调运方案进一步调整

你可能感兴趣的:(运输问题中表上作业法实现)