基于MATLAB的匈牙利算法实现任务分配
一、算法原理与核心步骤
匈牙利算法通过矩阵变换寻找最优分配方案,其核心步骤包括:
- 行约减:每行减去最小值,确保每行至少一个零
- 列约减:每列减去最小值,确保每列至少一个零
- 覆盖零:用最少的线覆盖所有零元素
- 调整矩阵:未覆盖元素减最小值,交点加最小值
- 重复迭代:直到找到完美匹配
数学建模示例:
成本矩阵 C = [[4, 2, 8],[6, 5, 7],[3, 9, 1]]
最优分配为总成本 3+5+1=9
二、MATLAB实现方案
1. 使用内置函数(推荐)
% 示例成本矩阵(任务数=代理数)
cost_matrix = [4, 2, 8; 6, 5, 7; 3, 9, 1];% 执行匈牙利算法
[assignment, total_cost] = hungarian(cost_matrix);% 输出结果
disp('最优分配方案:');
disp(assignment'); % 转置显示为任务→代理
disp(['最小总成本:', num2str(total_cost)]);
2. 手动实现算法
function [assignment, cost] = hungarian_manual(cost_matrix)n = size(cost_matrix, 1);cost_matrix = double(cost_matrix);% 步骤1:行约减row_min = min(cost_matrix, [], 2);cost_matrix = cost_matrix - row_min;% 步骤2:列约减col_min = min(cost_matrix, [], 1);cost_matrix = cost_matrix - col_min;% 步骤3:覆盖所有零while true[row_cover, col_cover] = find_cover(cost_matrix);if sum(row_cover) + sum(col_cover) == nbreak;end% 步骤4:调整矩阵[min_uncovered, pos] = find_min_uncovered(cost_matrix, row_cover, col_cover);cost_matrix(~row_cover, :) = cost_matrix(~row_cover,:) - min_uncovered;cost_matrix(:, col_cover) = cost_matrix(:, col_cover) + min_uncovered;end% 步骤5:提取匹配结果assignment = zeros(n,1);for i = 1:n[~, assignment(i)] = max(cost_matrix(i,:));endcost = sum(diag(cost_matrix));
end% 辅助函数实现
function [row_cover, col_cover] = find_cover(matrix)[n, m] = size(matrix);row_cover = false(n,1);col_cover = false(m,1);for i = 1:nfor j = 1:mif matrix(i,j) == 0 && ~row_cover(i) && ~col_cover(j)row_cover(i) = true;col_cover(j) = true;endendend
endfunction [min_val, pos] = find_min_uncovered(matrix, row_cover, col_cover)[n, m] = size(matrix);min_val = inf;pos = [0,0];for i = 1:nfor j = 1:mif ~row_cover(i) && ~col_cover(j)if matrix(i,j) < min_valmin_val = matrix(i,j);pos = [i,j];endendendend
end
三、应用案例解析
案例1:仓储机器人任务分配
% 机器人数量与任务数量
n = 5;
cost_matrix = randi([10, 100], n, n); % 随机生成成本矩阵% 添加虚拟节点处理非方阵(可选)
if size(cost_matrix,1) ~= size(cost_matrix,2)cost_matrix = [cost_matrix, inf(size(cost_matrix,1),1)];cost_matrix = [cost_matrix; inf(1,size(cost_matrix,2))];
end% 执行算法
[assignment, total_cost] = hungarian(cost_matrix(1:n,1:n));% 可视化结果
figure;
bar(assignment);
title('任务分配结果');
xlabel('机器人编号');
ylabel('分配任务编号');
案例2:动态任务分配(实时更新)
% 初始化参数
n_agents = 4;
n_tasks = 4;
cost_matrix = [3,5,7,2; 6,4,9,8; 2,3,5,4; 7,6,8,1];% 动态更新函数
function new_assignment = dynamic_update(old_assignment, cost_matrix)[~, new_assignment] = hungarian(cost_matrix);
end% 模拟动态变化
for iter = 1:5cost_matrix = cost_matrix + randn(size(cost_matrix))*2; % 添加噪声new_assignment = dynamic_update(assignment, cost_matrix);assignment = new_assignment;disp(['迭代', num2str(iter), '总成本:', num2str(sum(diag(cost_matrix(assignment,1:n_agents))))]);
end
四、性能优化策略
-
稀疏矩阵处理
对大规模稀疏矩阵使用压缩存储格式:
sparse_matrix = sparse(cost_matrix); [assignment, cost] = hungarian(sparse_matrix);
-
并行计算加速
options = optimoptions('hungarian','Display','iter','UseParallel',true); [assignment, cost] = hungarian(cost_matrix, options);
-
GPU加速
gpu_matrix = gpuArray(cost_matrix); [assignment, cost] = hungarian(gpu_matrix);
五、结果分析与验证
-
最优性验证
通过对比暴力搜索结果验证最优性:
brute_force_cost = min(sum(pdist2(cost_matrix, 'minkowski'))); assert(total_cost <= brute_force_cost*1.01); % 允许1%误差
-
可视化工具
% 绘制成本矩阵热力图 heatmap(cost_matrix); hold on; plot(find(assignment==1),1,'r*'); plot(find(assignment==2),2,'g*');
六、工程应用扩展
-
多代理系统
% 多机器人协同任务分配 num_agents = 10; num_tasks = 15; cost_matrix = rand(num_agents,num_tasks)*100; [assignment, cost] = hungarian(cost_matrix);
-
医疗资源调度
% 医院-患者匹配 hospitals = 5; patients = 7; cost_matrix = rand(hospitals,patients)*100; [assignment, cost] = hungarian(cost_matrix);
-
工业生产线优化
% 机器-工序匹配 machines = 6; processes = 6; cost_matrix = rand(machines,processes)*50; [assignment, cost] = hungarian(cost_matrix);
九、参考
- 核心文献 《运筹学》(清华大学出版社)第6章 《Combinatorial Optimization》 by Papadimitriou
- 代码 匈牙利算法实现任务分配 www.youwenfan.com/contentcsi/63742.html
- MATLAB工具箱 Global Optimization Toolbox Robotics System Toolbox