【有啥问啥】二分图(Bipartite Graph)算法原理详解

news2024/11/19 14:32:16

二分图

二分图(Bipartite Graph)算法原理详解

引言

二分图(Bipartite Graph),又称二部图,是图论中的一个重要概念。在实际应用中,二分图模型经常用于解决如匹配问题、覆盖问题和独立集问题等。本文将详细解析二分图的基本概念、性质、判定方法,以及求解最大匹配问题的匈牙利算法,并探讨其在实际中的应用。

  • 传送门链接: 图的数据结构(Graph Data Structures):深入探索与应用

1. 基本概念

1.1 定义

G = ( V , E ) G=(V,E) G=(V,E)是一个无向图,如果顶点集 V V V可以分割为两个互不相交的子集 A A A B B B,且图中的每条边 ( i , j ) (i,j) (i,j)所关联的两个顶点 i i i j j j分别属于这两个不同的顶点集(即 i ∈ A , j ∈ B i \in A, j \in B iA,jB),则称图 G G G为一个二分图。

1.2 性质

  1. 无向图G为二分图的充分必要条件

    • G中至少包含两个顶点。
    • G中所有回路的长度均为偶数。
  2. 二分图的匹配

    • G = < V , E > G=<V, E> G=<V,E>为二分图,如果 M ⊆ E M \subseteq E ME,并且 M M M中任意两条边都没有公共端点(即没有边共用一个顶点),则称 M M M G G G的一个匹配。
  3. 最大匹配

    • 在所有匹配中,边数最多的匹配称为最大匹配。
  4. 完备匹配与完全匹配

    • X X X中的所有顶点都是匹配 M M M中的端点,则称 M M M X X X的完备匹配。
    • M M M既是 X X X-完备匹配又是 Y Y Y-完备匹配,则称 M M M G G G的完全匹配(也称完美匹配)。

2. 判定方法

2.1 原理

无向图 G G G为二分图的一个充要条件是 G G G中不存在奇圈(即所有回路的长度均为偶数)。这一性质是二分图判定的核心依据。

2.2 实现方法

  1. 染色法

    • 任意选择一个顶点并赋予颜色1(或称为红色),放入集合 U U U
    • 将该顶点的所有未染色邻居顶点赋予颜色2(或称为蓝色),放入集合 V V V
    • 依次对集合 V V V中的每个顶点重复上述过程,直到所有顶点都被染色或发现矛盾(即存在边连接的两个顶点颜色相同)。
    • 如果所有顶点都被成功染色,则图是二分图;否则,不是二分图。
  2. 代码实现(DFS版本):

    def dfs(graph, color, vertex, color_value):
     """
     Perform DFS to color the graph and check if it's bipartite.
     """
     color[vertex] = color_value
     for neighbor in range(len(graph)):
         if graph[vertex][neighbor]:
             if color[neighbor] == -1:
                 if not dfs(graph, color, neighbor, 1 - color_value):
                     return False
             elif color[neighbor] == color_value:
                 return False
     return True
    
     def is_bipartite(graph):
         """
         Check if the given graph is bipartite.
         """
         n = len(graph)
         if n == 0:
             return True  # An empty graph is trivially bipartite
         
         color = [-1] * n
         for i in range(n):
             if color[i] == -1:
                 if not dfs(graph, color, i, 0):
                     return False
         return True
    

3. 匈牙利算法求解最大匹配

3.1 原理

匈牙利算法通过不断寻找增广路(也称为增广轨或交错轨)来增加匹配中的边数,直到无法找到新的增广路为止,此时得到的匹配即为最大匹配。

3.2 实现步骤

  1. 初始化匹配集 M M M为空集。
  2. 对每个未匹配点 u u u,执行:
    • u u u出发进行深度优先搜索(DFS),寻找一条增广路。
    • 如果找到增广路,则进行增广操作(即反转路径上边的匹配状态),并更新匹配集 M M M
    • 重复上述过程,直到无法找到新的增广路为止。

3.3 代码实现

def dfs(graph, match, visited, u):
    """
    Depth-first search to find an augmenting path in the bipartite graph.
    
    :param graph: Adjacency matrix of the bipartite graph.
    :param match: Current matching state.
    :param visited: Visited nodes in the current DFS.
    :param u: Current node to start DFS from.
    :return: True if an augmenting path is found, False otherwise.
    """
    for v in range(len(graph[u])):
        if graph[u][v] and not visited[v]:
            visited[v] = True
            if match[v] == -1 or dfs(graph, match, visited, match[v]):
                match[v] = u
                return True
    return False

def hungarian(graph):
    """
    Hungarian algorithm to find the maximum matching in a bipartite graph.
    
    :param graph: Adjacency matrix of the bipartite graph.
    :return: The size of the maximum matching.
    """
    n = len(graph)
    match = [-1] * n  # Initialize match array with -1 (no matches initially)
    result = 0
    
    for u in range(n):
        visited = [False] * n  # Reset visited array for each new DFS
        if dfs(graph, match, visited, u):
            result += 1
    
    return result

4. 应用场景

二分图算法在很多实际场景中都有应用,例如:

  • 推荐系统:通过建立用户和物品的二分图,利用最大匹配算法为用户推荐最感兴趣的物品。
  • 任务分配:在生产或项目管理中,将任务与可执行者建立二分图关系,利用匹配算法优化资源分配。
  • 社交网络:分析社交网络中的用户与兴趣之间的关系,找到最佳的匹配组合。

总结

二分图算法是图论中的一项重要技术,其应用范围广泛。本文详细解析了二分图的基本概念、性质、判定方法,以及求解最大匹配的匈牙利算法。通过理解和应用这些算法,我们可以有效地解决许多实际问题。希望本文能为读者在二分图算法的学习和应用中提供帮助。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

实验2思科网院项目2.7.2-packet-tracer---configure-single-area-ospfv2---实践练习

实践练习 2.7.2-packet-tracer---configure-single-area-ospfv2---实践练习physical-mode 实验拓扑 相关设备配置 实验目标: 第 1 部分&#xff1a;构建网络并配置设备的基本设置 第 2 部分&#xff1a;配置和验证单区域 OSPFv2 的基本部署 第 3 部分&#xff1a;优化和验…

【STM32】 TCP/IP通信协议(3)--LwIP网络接口

LwIP协议栈支持多种不同的网络接口&#xff08;网卡&#xff09;&#xff0c;由于网卡是直接跟硬件平台打交道&#xff0c;硬件不同则处理也是不同。那Iwip如何兼容这些不同的网卡呢&#xff1f; LwIP提供统一的接口&#xff0c;底层函数需要用户自行完成&#xff0c;例如网卡的…

动态时钟控件:Qt/C++ 项目代码解读

基于Qt的动态时钟控件项目。该项目展示了如何通过Qt的绘图系统绘制一个带有表盘背景、时针、分针、秒针、以及时间日期显示的时钟。同时&#xff0c;这个时钟控件支持背景切换&#xff0c;并且每秒钟刷新一次&#xff0c;实时显示当前时间。 项目结构与功能概述 该时钟控件主…

Redis接口访问优化

说明&#xff1a;之前写过一篇使用Redis接口访问的博客&#xff0c;如下。最近有相关需求&#xff0c;把代码拿出来后&#xff0c;做了一些优化&#xff0c;挺有意思的&#xff0c;本文介绍在原基础上 使用Redis实现接口防抖 优化 总的来说&#xff0c;这次使用Redis实现接口…

自动驾驶汽车横向控制方法研究综述

【摘要】 为实现精确、稳定的横向控制&#xff0c;提高车辆自主行驶的安全性和保障乘坐舒适性&#xff0c;综述了近年来自动驾驶汽车横向控制方法的最新进展&#xff0c;包括经典控制方法和基于深度学习的方法&#xff0c;讨论了各类方法的性能特点及在应用中的优缺点&#xff…

【初阶数据结构】详解插入排序 希尔排序(内含排序的概念和意义)

文章目录 前言1. 排序的概念及其应用1.1 排序的概念1.2 排序的应用 2. 插入排序2.1 基本思想2.2 插入排序的代码实现2.3 插入排序算法总结 3. 希尔排序3.1 基本思想3.2 希尔排序的代码实现3.3 希尔排序的特征总结 前言 初级数据结构系列已经进入到了排序的部分了。相信大家听到…

计算机毕业设计 服装生产信息管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

记录|Modbus-TCP产品使用记录【德克威尔】

目录 前言一、德克威尔1.1 实验图1.2 DECOWELL IO Tester 软件1.3 读写设置1.4 C#进行Modbus-TCP读写 更新时间 前言 参考文章&#xff1a; 使用的第二款Modbus-TCP产品。 一、德克威尔 1.1 实验图 1.2 DECOWELL IO Tester 软件 这也是自带模块配置软件的。下图就是德克威尔的…

“Xian”(籼)和“Geng”(粳)米怎么读?

2018年&#xff0c;《自然》上刊登了一篇有关亚洲栽培稻基因组变异的重磅论文。研究成果本身自然引人关注&#xff0c;但更引人关注的是&#xff0c;这篇论文首次提出以“Xian”&#xff08;籼&#xff09;和“Geng”&#xff08;粳&#xff09;两个汉语农业术语代替Indica和Ja…

yum使用阿里云的镜像源报错 Failed connect to mirrors.aliyuncs.com:80; Connection refused“

报错&#xff1a;Failed connect to mirrors.aliyuncs.com:80; Connection refused"&#xff0c;如果单独只是这个报错的话&#xff0c;那么原因是由于非阿里云ECS用户无法解析主机“mirrors.cloud.aliyuncs.com”。如果不单单只是这个报错另外还有其它报错请参考我其它文…

Threejs创建正多边体

上一章节实现了球体的绘制&#xff0c;这节来绘制多面体&#xff0c;包括正多面体&#xff0c;平面中&#xff0c;每条边一样长组成的图形叫正多边形&#xff0c;这里每个面一样&#xff0c;叫正多面体。如上文一样&#xff0c;先要创建出基础的组件&#xff0c;包括场景&#…

C++基础---类和对象(上)

1.类的定义 C程序设计允许程序员使用类&#xff08;class&#xff09;定义特定程序中的数据类型。这些数据类型的实例被称为对象 &#xff0c;这些实例可以包含程序员定义的成员变量、常量、成员函数&#xff0c;以及重载的运算符。语法上&#xff0c;类似C中结构体&#xff0…

【机器学习】任务六:分类算法(支持向量机(SVM)在线性可分与不可分数据中的应用与可视化分析)

目录 1.知识简介 2.SVM 支持向量机模型训练与可视化报告 2.1 导入本项目所需的模块和包 &#xff08;1&#xff09;目的 &#xff08;2&#xff09;代码实现 &#xff08;3&#xff09;代码解释 2.2 随机生成线性可分的数据并可视化 &#xff08;1&#xff09;目的 &a…

[数据集][目标检测]电力场景防震锤缺陷检测数据集VOC+YOLO格式705张1类别

重要说明&#xff1a;防震锤缺陷图片太难找&#xff0c;数据集里面存在大量单一场景图片&#xff0c;请仔细查看图片预览谨慎下载&#xff0c;此外数据集均为小目标检测&#xff0c;如果训练map偏低属于正常现象 数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径…

特殊的 BASE64 1

这个一看题目就是base64编码表被改了. 知识点&#xff1a; Base64编码使用一个包含64个字符的字符集&#xff0c;这些字符分别是&#xff1a; 大写字母A-Z小写字母a-z数字0-9特殊字符和/ 这些字符分别对应64个不同的6位二进制数。在补零后形成的8位字节中&#xff0c;实际使用…

c++primier第十二章类和动态内存

本章内容包括&#xff1a; 对类成员使用动态内存分配隐式和显式地复制构造函数隐式和显式地重载赋值操作符在构造函数中使用new所必须完成的工作使用静态类成员 将布局new操作符用于对象使用指向对象的指针实现队列抽象数据类型(ADT) 动态内存和类 复习范例和静态类成员 首…

ASP.NET Zero 多租户介绍

ASP.NET Zero 是一个基于 ASP.NET Core 的应用程序框架&#xff0c;它提供了多租户支持&#xff0c;以下是关于 ASP.NET Zero 多租户的介绍&#xff1a; 一、多租户概念 多租户是一种软件架构模式&#xff0c;允许多个客户&#xff08;租户&#xff09;共享同一套软件应用程序…

联邦学习(三只决策和大数据分析)(学习笔记)

联邦学习模型按照数据重叠形式分成了三类&#xff0c;分别是横向联邦学习、纵向联邦学习和联邦迁移学习。 横向联邦学习模型针对特征一致但ID不一致的数据&#xff1b; 纵向联邦学习模型针对ID一致但特征不一致的数据&#xff1b; 联邦迁移学习模型针对ID和特征都不一致的数据。…

Linux网络操作命令与函数全面总结

1. 引言 Linux作为服务器和开发平台&#xff0c;网络操作是其核心功能之一。本文旨在全面总结Linux系统中的网络操作方法&#xff0c;包括命令行工具和编程接口&#xff0c;帮助读者深入理解Linux网络管理的机制。 2. 命令行工具 2.1 ping 命令 ping 命令用于测试网络连接和…

实验OSPF路由协议(课内实验)

实验1&#xff1a;OSPF路由协议 实验目的及要求&#xff1a; 通过实验&#xff0c;能够理解链路状态型路由协议OSPF协议的工作原理&#xff0c;掌握如何实现单区域 OSPFv2配置指令&#xff0c;能够熟练的应用各种OSPF协议相关的配置指令完善网络设计。掌握验证OSPFv2网络连接…