MATLAB实现匈牙利算法求解二分图最大匹配

匈牙利算法(也称为Kuhn-Munkres算法)是解决二分图最大匹配问题的经典算法。

代码

function [matching, max_match] = hungarian_algorithm(adjMatrix)% HUNGARIAN_ALGORITHM 实现匈牙利算法求解二分图最大匹配% 输入:%   adjMatrix - 二分图的邻接矩阵,大小为m×n,m表示左侧顶点数,n表示右侧顶点数% 输出:%   matching - 匹配结果向量,matching(i)表示左侧第i个顶点匹配的右侧顶点索引(0表示未匹配)%   max_match - 最大匹配数[m, n] = size(adjMatrix);% 初始化匹配数组:matching_left表示左侧顶点的匹配,matching_right表示右侧顶点的匹配matching_left = zeros(1, m);    % 左侧匹配结果,初始为0(未匹配)matching_right = zeros(1, n);    % 右侧匹配结果,初始为0(未匹配)% 定义DFS函数用于寻找增广路径function found = dfs(u, visited)for v = 1:n% 如果存在边且右侧顶点v未被访问if adjMatrix(u, v) && ~visited(v)visited(v) = true;  % 标记右侧顶点v为已访问% 如果右侧顶点v未被匹配,或者已匹配的左侧顶点可以找到其他匹配if matching_right(v) == 0 || dfs(matching_right(v), visited)matching_left(u) = v;       % 将左侧u匹配到右侧vmatching_right(v) = u;      % 将右侧v匹配到左侧ufound = true;               % 找到增广路径return;endendendfound = false;  % 未找到增广路径end% 主算法:对每个左侧顶点尝试寻找匹配for u = 1:mvisited = false(1, n);  % 初始化访问标记数组dfs(u, visited);        % 尝试为当前左侧顶点u寻找匹配end% 统计匹配数max_match = sum(matching_left > 0);% 返回左侧匹配结果matching = matching_left;
end

算法测试与示例

1:简单二分图

% 创建邻接矩阵 (3x3)
adjMatrix = [1, 0, 1;  % 左侧顶点1连接右侧顶点1和30, 1, 0;  % 左侧顶点2连接右侧顶点21, 1, 0;  % 左侧顶点3连接右侧顶点1和2
];% 运行匈牙利算法
[matching, max_match] = hungarian_algorithm(adjMatrix);% 显示结果
disp('匹配结果:');
for i = 1:length(matching)if matching(i) > 0fprintf('左侧顶点 %d 匹配到右侧顶点 %d\n', i, matching(i));elsefprintf('左侧顶点 %d 未匹配\n', i);end
end
fprintf('最大匹配数: %d\n', max_match);

2:更大规模的二分图

% 创建随机二分图 (10x8)
rng(42); % 设置随机种子确保可重复性
adjMatrix = randi([0, 1], 10, 8); % 随机生成0-1矩阵% 运行匈牙利算法
[matching, max_match] = hungarian_algorithm(adjMatrix);% 显示结果
disp('邻接矩阵:');
disp(adjMatrix);disp('匹配结果:');
disp(matching);
fprintf('最大匹配数: %d\n', max_match);% 可视化结果
figure;
hold on;
title('二分图匹配结果');
xlim([0, 3]);
ylim([0, max(10, 8)+1]);% 绘制左侧顶点
for i = 1:10plot(0.5, i, 'bo', 'MarkerSize', 10, 'MarkerFaceColor', 'b');text(0.4, i, sprintf('L%d', i));
end% 绘制右侧顶点
for j = 1:8plot(2.5, j, 'ro', 'MarkerSize', 10, 'MarkerFaceColor', 'r');text(2.6, j, sprintf('R%d', j));
end% 绘制所有边
for i = 1:10for j = 1:8if adjMatrix(i, j)plot([0.5, 2.5], [i, j], 'k:', 'LineWidth', 0.5);endend
end% 绘制匹配边
for i = 1:10if matching(i) > 0plot([0.5, 2.5], [i, matching(i)], 'g-', 'LineWidth', 2);end
endlegend('左侧顶点', '右侧顶点', '可能边', '匹配边');
hold off;

算法分析与解释

匈牙利算法核心思想

匈牙利算法基于以下关键概念:

  1. 增广路径:从一个未匹配顶点开始,交替经过匹配边和非匹配边,最终到达另一个未匹配顶点的路径
  2. 核心操作:找到一条增广路径并"翻转"路径上的边(匹配变非匹配,非匹配变匹配),从而增加匹配数

MATLAB实现特点

  1. 深度优先搜索(DFS):使用递归DFS寻找增广路径
  2. 高效匹配:时间复杂度为O(mn),其中m和n分别是左右两侧顶点数
  3. 简洁实现:利用递归函数和访问标记数组优化搜索过程

算法步骤详解

  1. 初始化

    • 创建匹配数组matching_leftmatching_right,初始化为0(未匹配)
  2. 遍历左侧顶点

    • 对每个左侧顶点u,尝试寻找匹配的右侧顶点
  3. DFS寻找增广路径

    • 标记已访问的右侧顶点
    • 对于当前左侧顶点u连接的每个右侧顶点v:
      • 如果v未访问,则标记为已访问
      • 如果v未匹配,或者v已匹配但可以找到替代匹配,则更新匹配
  4. 更新匹配

    • 当找到增广路径时,更新匹配关系
  5. 结果统计

    • 计算并返回最大匹配数

参考代码 matlab实现匈牙利算法二分图最大匹配的程序 www.youwenfan.com/contentcsd/97883.html

应用场景

匈牙利算法在以下领域有广泛应用:

  1. 任务分配:将任务分配给最合适的工人
  2. 资源调度:最优资源分配问题
  3. 图像处理:特征点匹配
  4. 网络流:求解最大流问题的辅助算法
  5. 化学:分子结构中的键合分析

性能优化建议

对于大型二分图,可以考虑以下优化:

% 优化版本:添加早期终止和预处理
function [matching, max_match] = optimized_hungarian(adjMatrix)[m, n] = size(adjMatrix);matching_left = zeros(1, m);matching_right = zeros(1, n);% 预处理:先尝试贪心匹配for u = 1:mfor v = 1:nif adjMatrix(u, v) && matching_right(v) == 0 && matching_left(u) == 0matching_left(u) = v;matching_right(v) = u;endendendfunction found = dfs(u, visited)for v = 1:nif adjMatrix(u, v) && ~visited(v)visited(v) = true;% 使用匹配数组直接访问,提高效率if matching_right(v) == 0 || dfs(matching_right(v), visited)matching_left(u) = v;matching_right(v) = u;found = true;return;endendendfound = false;end% 只对未匹配的左侧顶点尝试DFSfor u = 1:mif matching_left(u) == 0visited = false(1, n);dfs(u, visited);endendmax_match = sum(matching_left > 0);matching = matching_left;
end

此优化版本添加了:

  1. 贪心预处理:先进行简单匹配,减少后续DFS次数
  2. 条件DFS:只对未匹配的左侧顶点进行DFS
  3. 直接访问:避免重复计算

匈牙利算法是解决二分图匹配问题的高效方法,本实现提供了清晰的MATLAB代码和示例,可直接应用于各种匹配问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/93739.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/93739.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/93739.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自定义table

更好<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"utf-8"><title>数据表格</title><style>* {margin: 0;padding: 0;box-sizing: border-box;font-size: 14px;}html,body {width: 100%;height: 100%…

面向R语言用户的Highcharts

如果您喜欢使用 R 进行数据科学创建交互式数据可视化&#xff0c;那么请你收藏。今天&#xff0c;我们将使用折线图、柱状图和散点图来可视化资产回报。对于我们的数据&#xff0c;我们将使用以下 5 只 ETF 的 5 年月回报率。 SPY (S&P500 fund)EFA (a non-US equities fun…

【测试工具】OnDo SIP Server--轻松搭建一个语音通话服务器

前言 Ondo SIP Server 是一款基于 SIP(Session Initiation Protocol)协议的服务器软件&#xff0c;主要用于实现 VoIP(Voice over IP)通信&#xff0c;支持语音通话、视频会议等多媒体会话管理&#xff0c;非常适合学习和测试VoIP的基本功能。本文介绍Ondo SIP Server的安装、…

疯狂星期四文案网第42天运营日记

网站运营第42天&#xff0c;点击观站&#xff1a; 疯狂星期四 crazy-thursday.com 全网最全的疯狂星期四文案网站 运营报告 今日访问量 今日搜索引擎收录情况 网站优化点 优化一些发现的seo错误 增加颜文字栏目 增加了一些tag

使用空模型实例调用辅助函数,确定在量化过程中哪些层会被跳过(43)

在Facebook的OPT-350M中,模型的头部(lm_head)与解码器的嵌入标记层(decoder.embed_tokens)共享其权重。 print(model.model.decoder.embed_tokens) print(model.lm_head)输出结果 Embedding(50272, 512

从0-1使用Fastmcp开发一个MCP服务,并部署到阿里云百炼 -持续更新中

目的&#xff1a; 在本地使用fastmcp开发一个mcp,然后注册到阿里云的百炼里面。实现在百炼里面创建智能体的时候直接引用自己开发的MCP 已完成&#xff1a;本地环境安装 待完成&#xff1a; 1.根据需求实现一个MCP中可以调用某应用的多个API即 mcp.tool()、mcp.prompt()、接入大…

设计模式之汇总

设计模式 零、设计原则 0.1 单一职责 0.2 接口隔离 0.3 开闭原则 0.4 依赖倒置0.5 迪米特法则&#xff0c;最小知道原则用户关机 只和朋友通信 朋友条件&#xff1a; 1&#xff09;当前对象本身&#xff08;this&#xff09; 2&#xff09;以参量形式传入到当前对象方法中的对象…

第6章 Decoder与Encoder核心组件

前言 Netty从底层Java通道读取ByteBuf二进制数据&#xff0c;传入Netty通道的流水线&#xff0c;随后开始入站处理。在入站处理过程中&#xff0c;需要将ByteBuf二进制类型解码成Java POJO对象。这个解码过程可以通过Netty的Decoder&#xff08;解码器&#xff09;去完成。 在…

[已解决]当启动 Spring Boot 应用时出现 Using generated security password xxx提示

当启动 Spring Boot 应用时出现 Using generated security password xxx提示当启动 Spring Boot 应用时出现 Using generated security password xxx提示&#xff0c;这是 Spring Security 自动配置的默认行为&#xff0c;通常发生在你​​未自定义安全配置​​但引入了 Spring…

自动分析需求,PRD 生成只需 SOLO 一步!

资料来源&#xff1a;火山引擎-开发者社区 写不清需求&#xff1f;PRD 难产&#xff1f;开发总跑偏&#xff1f;这些痛点&#xff0c;SOLO 来解决。 TRAE SOLO 是行业首个 Context Engineer。它不止协助编码&#xff0c;更能基于精准上下文理解和工具调用&#xff0c;从构思、…

物联网软件开发过程中,数据流图(DFD),用例图,类图,活动图,序列图,状态图,实体关系图(ERD),BPMN(业务流程建模)详解分析

概述软件开发过程中&#xff0c;特别是在物联网&#xff08;IoT&#xff09;场景中&#xff0c;数据流图&#xff08;DFD&#xff09;、UML图&#xff08;包括用例图、类图、活动图、序列图、状态图&#xff09;、实体关系图&#xff08;ERD&#xff09;和业务流程建模&#xf…

Mac(一)常用的快捷键整理

目录1、系统操作与窗口管理2、应用与窗口切换3、常规编辑操作4、文本导航与光标控制✏️5、文本格式与文档功能&#xff08;支持应用中&#xff09;6、截图快捷键7、Safari 浏览器快捷键8、Finder 快捷键&#xff08;文件管理&#xff09;9、Fn / Globe 功能键&#xff08;部分…

HAProxy使用方法以及和LVS区别

HAProxy简介HAProxy是法国开发者 威利塔罗(Willy Tarreau) 在2000年使用C语言开发的一个开源软件 是一款具备高并发(万级以上)、高性能的TCP和HTTP负载均衡器 支持基于cookie的持久性&#xff0c;自动故障切换&#xff0c;支持正则表达式及web状态统计LVS 与 HAProxy 的核心区别…

超越“小作文”:大模型指令设计的进阶之路——优化知识信噪比

文章摘要&#xff1a;你是否认为&#xff0c;给大模型的指令&#xff08;Prompt&#xff09;写得越详细越好&#xff1f;真的是信息越多&#xff0c;模型就越懂你吗&#xff1f;本文将深入探讨一个反直覺的觀點&#xff1a;初級的指令設計專注於資訊的堆砌&#xff0c;而高階的…

elasticsearch-集成prometheus监控(k8s)

一. 简介&#xff1a; 关于elasticsearch的简介和部署&#xff0c;可以参考单独的文章elasticsearch基础概念与集群部署-CSDN博客&#xff0c;这里就不细说了。这里只讲讲如何在k8s中部署export并基于prometheus做es的指标采集。 二. 实现方式&#xff1a; 首先我们需要先部署…

贪心算法(Greedy Algorithm)详解

一、什么是贪心算法&#xff1f; 贪心算法是一种算法设计范式&#xff0c;指在解决问题时&#xff0c;依赖于每次选择最优的局部解&#xff0c;以期最终得到全局最优解。贪心算法的关键特点是&#xff1a; 局部最优选择&#xff1a;每个阶段选择当前看起来最好的选择&#xff0…

电梯的构造|保养|维修视频全集_电梯安全与故障救援(课程下载)

课程下载&#xff1a;https://download.csdn.net/download/m0_66047725/91699586 电梯原理与维修视频教程 相关简介: 电梯现在运用的非常广泛,比如大型商场,建筑工地,特别是现在建造的很多高楼、商品房,基本都是安装了电梯。电梯维保不力是导致电梯运行中安全事故频发的主要原…

Traefik网关DNS解析超时问题优化

1、背景 在生产环境使用 Traefik 网关时出现了偶发的 DNS 解析超时导致网关与后端服务建立连接异常的情况。通过调用链埋点数据观察发现&#xff0c;该部署环境中 Traefik 的 DNS 解析性能较差&#xff0c;耗时通常在 4ms 以上&#xff08;正常应该是 1ms 以内&#xff09; 初…

从0到1掌握 Spring Security(第三篇):三种认证方式,按配置一键切换

> 本文是Spring Security系列第三篇,将带你实现内存、JDBC和自定义三种认证方式的无缝切换,只需修改配置文件即可完成认证策略变更! ## 一、为什么需要多种认证方式? 在软件开发的不同阶段,我们需要不同的认证策略: - **开发阶段**:使用内存认证,快速配置测试账号…

阿里云国际站云防火墙:如何利用阿里云云防火墙实现细粒度的访问控制?

利用阿里云云防火墙实现细粒度的访问控制&#xff0c;可以从分层策略、精确匹配、动态调整三个方面着手&#xff0c;让不同业务、用户和资源的访问权限清晰可控。一、明确控制目标业务隔离&#xff1a;不同业务系统、部门或环境&#xff08;生产/测试&#xff09;之间互不干扰。…