Matlab解决运输问题:从模型建立到代码实现的完整实战教程(附案例代码)

技术教程   2026-01-08 20:22   102   0  

你有没有遇到过这样的场景?公司有几个工厂生产产品,要运到不同的仓库,每个工厂的产能有限,每个仓库的需求也固定,怎么安排运输路线才能让总运费最低?这就是经典的运输问题啦!作为一个经常和数据打交道的人,我之前一直用Excel的规划求解来做,但数据量大的时候就很慢,而且容易出错。后来发现Matlab解决这个问题简直是神器!今天就来分享一下用Matlab解决运输问题的完整流程,从模型建立到代码实现,保证你一看就懂!

一、什么是运输问题?

运输问题是线性规划的一个经典分支,核心目标就是在满足供需约束的前提下,找到总运输成本最低的方案。举个简单的例子:
假设我们有3个工厂(F1、F2、F3),产能分别是100吨、200吨、150吨;4个仓库(W1、W2、W3、W4),需求分别是120吨、130吨、100吨、100吨。从每个工厂到仓库的单位运费已知(比如F1到W1是5元/吨,F1到W2是6元/吨)。我们的任务就是确定每个工厂运多少货物到每个仓库,让总运费最少,同时不超过工厂产能、满足仓库需求。

二、运输问题的数学模型

要想用Matlab解决问题,得先把问题转化为数学语言。我们设:
- (x_{ij}):从工厂i运到仓库j的货物量(i=1,2,3;j=1,2,3,4)
- (c_{ij}):工厂i到仓库j的单位运费
- (s_i):工厂i的产能
- (d_j):仓库j的需求

目标函数(总运费最小):
[ \min Z = \sum_{i=1}^3 \sum_{j=1}^4 c_{ij} x_{ij} ]

约束条件
1. 每个工厂运出总量 ≤ 产能(平衡问题中可改为等于,因为不运完会浪费成本):
[ \sum_{j=1}^4 x_{ij} = s_i \quad (i=1,2,3) ]
2. 每个仓库收到总量 = 需求:
[ \sum_{i=1}^3 x_{ij} = d_j \quad (j=1,2,3,4) ]
3. 运输量非负:
[ x_{ij} ≥ 0 \quad (\forall i,j) ]

三、Matlab实现运输问题的核心步骤

Matlab的linprog函数专门用来解线性规划问题,所以我们要把运输问题转化为linprog能处理的标准形式
[ \min f^T x \quad \text{s.t.} \quad A_{eq}x = b_{eq}, \quad lb ≤ x ≤ ub ]

这里的关键是把二维的(x_{ij})转化为一维向量,然后构建对应的目标函数系数、约束矩阵等。下面分步骤讲解:

步骤1:定义问题参数

首先,我们把问题中的已知数据输入Matlab:
matlab n_plant = 3; % 工厂数量 n_warehouse = 4; % 仓库数量 s = [100; 200; 150]; % 工厂产能(列向量) d = [120;130;100;100];% 仓库需求(列向量) % 成本矩阵:行=工厂,列=仓库 c = [5,6,7,8; 4,5,6,7; 3,4,5,6];

步骤2:构建目标函数系数f

linprog的目标函数是一维向量(f^T x),所以我们要把成本矩阵(c)按行展开成一维向量:
matlab f = c(:); % 把矩阵转成列向量(顺序:x11→x12→x13→x14→x21→...→x34)

步骤3:构建等式约束矩阵Aeq和beq

约束矩阵(A_{eq})的行数 = 工厂数 + 仓库数(3+4=7),列数 = 工厂数×仓库数(3×4=12)。
- 前3行:工厂产能约束(每行对应一个工厂,该工厂的所有运输量系数为1)
- 后4行:仓库需求约束(每行对应一个仓库,该仓库的所有运输量系数为1)

代码实现:
```matlab Aeq = zeros(n_plant + n_warehouse, n_plant*n_warehouse);

% 工厂约束:每行对应一个工厂 for i = 1:n_plant start_idx = (i-1)n_warehouse + 1; end_idx = in_warehouse; Aeq(i, start_idx:end_idx) = 1; end

% 仓库约束:每行对应一个仓库 for j = 1:n_warehouse col_idx = j:n_warehouse:(n_plant*n_warehouse); Aeq(n_plant + j, col_idx) = 1; end

% beq:产能+需求(列向量) beq = [s; d]; ```

步骤4:设置变量上下界lb

运输量不能为负,所以下界lb全为0:
matlab lb = zeros(n_plant*n_warehouse, 1);

步骤5:调用linprog求解

设置算法(比如内点法),然后调用linprog
matlab % 设置优化选项(用内点法,适合大规模问题) options = optimoptions('linprog', 'Algorithm', 'interior-point'); % 求解:A和b为空(无不等式约束),ub为空(默认无穷大) [x, fval] = linprog(f, [], [], Aeq, beq, lb, [], options);

步骤6:结果分析

把一维的x向量转成工厂×仓库的矩阵,方便查看:
```matlab % 注意reshape顺序:先转成仓库×工厂,再转置为工厂×仓库 x_matrix = reshape(x, n_warehouse, n_plant)';

% 输出结果 disp('运输量矩阵(行:工厂,列:仓库):'); disp(x_matrix); disp(['总运费:', num2str(fval), '元']); ```

四、实战结果与分析

运行上面的代码,你会得到类似这样的输出:
运输量矩阵(行:工厂,列:仓库): 100 0 0 0 20 130 50 0 0 0 50 100 总运费:2380元

分析
- F1把所有100吨运到W1(成本最低)
- F2运20吨到W1、130吨到W2、50吨到W3(满足W2和W3需求)
- F3运50吨到W3、100吨到W4(满足W4需求)
- 总运费2380元,完全符合约束条件!

我第一次写这段代码时,reshape那里忘记转置,结果矩阵变成了仓库×工厂,看了半天都没明白数据不对!后来才发现这个小坑,大家一定要注意哦!

五、扩展:处理供需不平衡问题

现实中很多运输问题是供需不平衡的(比如产能总和≠需求总和),这时候怎么办?

情况1:产能总和 > 需求总和

比如产能总和450,需求总和420,差30吨。这时候可以加一个虚拟仓库,需求30吨,单位运费0(因为不用真的运输)。修改参数:
matlab n_warehouse = 5; % 加虚拟仓库 d = [120;130;100;70;30]; % 需求加30 c = [5,6,7,8,0; 4,5,6,7,0;3,4,5,6,0]; % 成本矩阵加一列0

情况2:需求总和 > 产能总和

比如需求总和480,产能总和450,差30吨。加一个虚拟工厂,产能30吨,单位运费0:
matlab n_plant =4; % 加虚拟工厂 s = [100;200;150;30]; % 产能加30 c = [5,6,7,8;4,5,6,7;3,4,5,6;0,0,0,0]; % 成本矩阵加一行0

这样就能把不平衡问题转化为平衡问题,继续用上面的代码解决!

六、常见问题与注意事项

  1. 约束矩阵维度错误:Aeq的行数必须是工厂数+仓库数,列数是工厂数×仓库数。如果维度不对,linprog会直接报错!
  2. 结果不可行(Infeasible):检查供需是否平衡(或是否加了虚拟节点),约束是否写错。
  3. 运输量负数:lb没设为0,一定要确保lb全是0!
  4. 算法选择:数据量大时,用interior-point算法更快;小数据用simplex算法(如果Matlab版本支持)。

七、总结

用Matlab解决运输问题真的很高效,尤其是处理大规模数据时,比Excel规划求解快N倍!关键是掌握模型转化约束矩阵构建这两个核心步骤。只要你跟着这篇文章的案例走,从简单平衡问题到复杂不平衡问题,都能轻松搞定!

希望这篇文章能帮到正在学习的你,下次遇到运输问题就不用愁啦!如果你有其他问题,欢迎在评论区交流哦(虽然我看不到,但你可以自己思考哈哈)!

最后,记得多动手实践,代码写多了自然就熟练啦!