多商品流问题介绍及MATLAB代码实现

多商品流问题的定义

多商品流问题(Multi-Commodity Flow Prolem)是多种商品(或货物)在网络中从不同的源节点流到不同宿节点的网络流问题。多商品流问题的目标是以最小的成本实现商品在网络中的流通,且不能超过每条边的承载能力。具体解释网上已经很多,本文不再赘述。

模型建立

多商品流的模型主要包含流守恒约束和容量限制两个方面。
给定一个通信网络拓扑图 G ( V , E ) G(V,E) G(V,E),其 V V V表示的是所有节点的集合, E E E表示所有链路的集合, G ( V , E ) G(V,E) G(V,E)表示整个拓扑。接下来给定部分或者全部节点对之间的流量需求:

  1. 共计K个这样的需求,编号 k = 1 , 2 , … , K k=1,2,…,K k=1,2,,K
  2. k k k个需求的大小为 h k h_k hk,第 k k k个需求下的源端点和宿端点分别为 s k s_k sk d k d_k dk。除了源宿端点外的其他节点,比如节点 i i i,用 v i v_i vi表示; l i j l_{ij} lij表示节点 i i i j j j之间的链路边;第 k k k个需求下 l i j l_{ij} lij的边上的流量用 x i j k x_{ij}^k xijk表示。另外,网络拓扑中每条边上的单位流量代价为 C i j C_{ij} Cij边的带宽即容量为 b i j b_{ij} bij
    目标函数
    min ⁡ ∑ i ∑ j d i j x i j \min \sum\limits_i {\sum\limits_j {{d_{ij}}{x_{ij}}} } minijdijxij
    约束条件
    ∑ j : ( s k , j ) ∈ E x s k j k − ∑ j : ( j , s k ) ∈ E x j s k k = h k , k = 1 , 2 , 3 , . . . , K \sum\limits_{j:({s^k},j) \in E} {x_{{s^k}j}^k} - \sum\limits_{j:(j,{s^k}) \in E} {x_{j{s^k}}^k} = {h^k},k = 1,2,3,...,K j:(sk,j)Exskjkj:(j,sk)Exjskk=hk,k=1,2,3,...,K
    ∑ j : ( d k , j ) ∈ E x d k j k − ∑ j : ( j , d k ) ∈ E x j d k k = − h k , k = 1 , 2 , 3 , . . . , K \sum\limits_{j:({d^k},j) \in E} {x_{{d^k}j}^k} - \sum\limits_{j:(j,{d^k}) \in E} {x_{j{d^k}}^k} = - {h^k},k = 1,2,3,...,K j:(dk,j)Exdkjkj:(j,dk)Exjdkk=hk,k=1,2,3,...,K
    ∑ j : ( i , j ) ∈ E , i ≠ s k , d k x i j k − ∑ j : ( j , i ) ∈ E , i ≠ s k , d k x j i k = 0 , k = 1 , 2 , 3 , . . . , K \sum\limits_{j:(i,j) \in E,i \ne {s^k},{d^k}} {x_{ij}^k} - \sum\limits_{j:(j,i) \in E,i \ne {s^k},{d^k}} {x_{ji}^k} = 0,k = 1,2,3,...,K j:(i,j)E,i=sk,dkxijkj:(j,i)E,i=sk,dkxjik=0,k=1,2,3,...,K
    ∑ k x i j k ≤ b i j , ∀ i , j \sum\limits_k {x_{ij}^k} \le {b_{ij}},\forall i,j kxijkbij,i,j
    x i j k ≥ 0 , ∀ i , j , k x_{ij}^k \ge 0,\forall i,j,k xijk0,i,j,k

具体实现代码

%% 多商品流模型 
% edit by QIU
% 清除工作区
clear;clc;close all;
%需求定义为三元组,源节点、目的节点和需求
h = [1 3 5
     1 2 3
     2 3 3
     3 1 5
     3 2 10];
%底层网络拓扑邻接矩阵
b = [100 60 70
     70 100 60 
     70 80 109];
d = [1 2 3
     2 1 3 
     2 3 1]; 

% 创建决策变量
[m,n] = size(b);
l = size(h,1);
x = intvar(m,n,l,'full');

%% 添加约束条件
C = [ ];
%源节点约束
for i=1:l
    s = sum(x(h(i,1),:,i)) - sum(x(:,h(i,1),i));
    C = [C, s == h(i,3)];
end
%目标节点约束
for i=1:l
    s = sum(x(h(i,2),:,i)) - sum(x(:,h(i,2),i));
    C = [C, s == -h(i,3)];
end
%中间节点约束
for k=1:l
    for i=1:3
        if i ~= h(k,1) && i ~= h(k,2)
            s = sum(x(i,:,k)) - sum(x(:,i,k));
            C = [C, s == 0];
        end
    end
end
%链路容量约束
for i=1:3
    for j=1:3
        X(i,j) = sum(x(i,j,:));
        C = [C, sum(x(i,j,:)) <= b(i,j)];
    end
end
%变量取值范围约束
C = [C, x>=0]; 
%% 配置
ops = sdpsettings('verbose',0,'solver','cplex');
% 目标函数
z = sum(sum(d.*X)); %求解最小值,求解最大值需要添加负号
% 求解
reuslt = optimize(C,z);
if reuslt.problem == 0 % problem =0 代表求解成功
    value(x)
    value(z)
    value(X)
else
    disp('求解出错');
end

对代码的一些介绍

模型的求解采用yalmip和CPLEX工具,具体安装网上已有教程,可自行查阅。
代码中采用三维整数变量(具体类型根据需求定义,yalmip支持实数,整数和0-1变量),每一页对应每个需求的变量。定义了一些常量为了提高代码的扩展性。

谈谈自己的一些想法

多商品流问题在网络中非常实用,可以根据需求进行不同种类的变形。例如,如果定义变量为二值变量时,可以控制单路径路由,避免流量分割。也非常欢迎有兴趣的小伙伴交流,共同进步!

  • 6
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值