精华内容
下载资源
问答
  • 2021-08-04 15:18:52

    理论知识网上有很多,只根据代码解析下:
    矩阵为:(每一列代表一个男生,每一行代表一个女生,1代表匹配,0代表不匹配)
    0 0 0 1 1 1 0 0 0 1 0 1 0 0 0 1 0 0 1 1 1 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 \begin{matrix} 0 & 0 & 0 & 1 & 1 & 1 \\ 0 & 0 & 0 & 1 & 0 & 1 \\ 0 & 0 & 0 & 1 & 0 & 0 \\ 1 & 1 & 1 & 0 & 0 & 0 \\ 1 & 0 & 0 & 0 & 0 & 0 \\ 1 & 1 & 0 & 0 & 0 & 0 \end{matrix} 000111000101000100111000100000110000
    1.id=0的男生和id=3的女生匹配,再去找id=1的男生,发现与id=3也匹配,对id=0的男生重新寻找,找到id=4的女生匹配。
    2.id=2的男生和id=3的女生匹配,发现id=1的男生与id=3匹配,对id=1的男生重新寻找,找到id=5的女生匹配,且id=5的女生还未和其他人建立匹配。
    3.依次类推,直至建立所有匹配关系。

    class Hungary():
        def __init__(self,graph):
            self.graph = graph
            self.n = len(graph)
            self.used = None
            self.nxt = None
            
        def find(self,x):
            for i in range(self.n):
                if self.graph[i][x] == 1 and self.used[i] == 0:
                	# 找到满足匹配关系且还没有建立匹配的对象
                    self.used[i] = 1
                    # 还未建立匹配关系或者男生还有别的匹配对象
                    if self.nxt[i] == -1 or self.find(self.nxt[i]):
                    	# 保存男生匹配id和女生匹配id
                        self.nxt[x] = i
                        self.nxt[i] = x
                        return True
            return False
    
        def match(self):
            self.used = [False] * self.n
            self.nxt = [-1] * self.n
            for i in range(self.n):
                if self.nxt[i] == -1:
                	# self.used初始化
                    self.used = [False] * self.n
                    self.find(i)
    
    更多相关内容
  • 匈牙利匹配算法的matlab版demo和C语言版demo
  • 匈牙利匹配实验测试数据
  • 目标跟踪中匈牙利匹配

    目标跟踪中的匈牙利匹配( associate_detections_to_trackers()):
    先计算相似度矩阵:sort中之计算检测框和轨迹的iou。
    代价矩阵:cost_matrix就是-iou_matrix。
    以下代码中,两种方式计算对应索引的匹配:
    1、一一对应的话直接出结果;
    2、不是一一对应的话,就用scipy的linear_sum_assignment。
    理论参考:
    https://zhuanlan.zhihu.com/p/459758723
    https://blog.csdn.net/lzzzzzzm/article/details/122634983

    以下代码中,用到的测试数据可以通过数据链接下载。

    # -*- coding: utf-8 -*-
    """
    Time    : 2022/5/12 19:20
    Author  : cong
    """
    from scipy.optimize import linear_sum_assignment
    import numpy as np
    
    
    def iou_batch(bb_test, bb_gt):
        """
      From SORT: Computes IOU between two bboxes in the form [x1,y1,x2,y2]
      """
        bb_gt = np.expand_dims(bb_gt, 0)
        bb_test = np.expand_dims(bb_test, 1)
    
        xx1 = np.maximum(bb_test[..., 0], bb_gt[..., 0])
        yy1 = np.maximum(bb_test[..., 1], bb_gt[..., 1])
        xx2 = np.minimum(bb_test[..., 2], bb_gt[..., 2])
        yy2 = np.minimum(bb_test[..., 3], bb_gt[..., 3])
        w = np.maximum(0., xx2 - xx1)
        h = np.maximum(0., yy2 - yy1)
        wh = w * h
        o = wh / ((bb_test[..., 2] - bb_test[..., 0]) * (bb_test[..., 3] - bb_test[..., 1])
                  + (bb_gt[..., 2] - bb_gt[..., 0]) * (bb_gt[..., 3] - bb_gt[..., 1]) - wh)
        return o
    
    
    iou_threshold = 0.3
    dets = np.load('dets.npy')
    tracks = np.load('trks.npy')
    # 计算iou相似度矩阵
    iou_matrix = iou_batch(dets, tracks)
    
    if min(iou_matrix.shape) > 0:
        a = (iou_matrix > iou_threshold).astype(np.int32)
        # axis=1以后就是将一个矩阵的每一行向量相加,0:列相加
        # 每行的元素相加, 求出所有行的max为1,所有列max为1,
        # 如果大于0.3的位置恰好一一对应,可直接得到匹配结果,否则利用匈牙利算法进行匹配
        if a.sum(1).max() == 1 and a.sum(0).max() == 1:
            # np.where(a) 找出符合条件的元素索引
            print('*'*20)
            matched_indices = np.stack(np.where(a), axis=1) # ndarray
        else:
            x,y = linear_sum_assignment(-iou_matrix) # tuple
            matched_indices = np.array(list(zip(x, y)))
    
    unmatched_detections = []
    for d, det in enumerate(dets):
        if d not in matched_indices[:, 0]:
            unmatched_detections.append(d)
    unmatched_trackers = []
    for t, trk in enumerate(tracks):
        if t not in matched_indices[:, 1]:
            unmatched_trackers.append(t)
    
    # filter out matched with low IOU
    matches = []
    for m in matched_indices:
        if iou_matrix[m[0], m[1]] < iou_threshold:
            unmatched_detections.append(m[0])
            unmatched_trackers.append(m[1])
        else:
            matches.append(m.reshape(1, 2))
    if len(matches) == 0:
        matches = np.empty((0, 2), dtype=int)
    else:
        matches = np.concatenate(matches, axis=0)
    
    
    
    
    
    展开全文
  • 文中提出基于匈牙利匹配的钓鱼网页检测模型,该模型首先提取渲染后网页的文本特征签名、图像特征签名以及网页整体特征签名,比较全面地刻画了网页访问后的特征;然后通过匈牙利算法计算二分图的最佳匹配来寻找不同网页...
  • 匈牙利匹配算法原理

    千次阅读 2019-05-27 22:21:12
    文章目录图论中的基本概念匈牙利算法中的基本概念匈牙利匹配算法匈牙利匹配算法举例匈牙利匹配算法Python代码实现 图论中的基本概念 二分图: 一个图中的所有顶点可划分为两个不相交的集合 U 和 V ,使得每一条边都...

    图论中的基本概念

    二分图:
    一个图中的所有顶点可划分为两个不相交的集合 U 和 V ,使得每一条边都分别连接U、V中的顶点。如果存在这样的划分,则此图为一个二分图。
    匹配:
    一个匹配就是一个边的集合,这个边集合中的任意两条边没有公共的顶点。
    最大匹配:
    一个图的所有匹配中,所含匹配边数最多的匹配,称为这个图的最大匹配。
    最大匹配数:
    最大匹配的匹配边的数目。
    完美匹配:
    如果一个图的某个匹配中,所有的顶点都是匹配点,那么它就是一个完美匹配。显然,完美匹配一定是最大匹配(完美匹配的任何一个点都已经匹配,添加一条新的匹配边一定会与已有的匹配边冲突)。但并非每个图都存在完美匹配。
    最小顶点覆盖数:
    选取最少的点,使二分图中任意一条边至少有一个端点被选择。最小覆盖要求用最少的点(U集合或V集合的都行)让每条边都至少和其中一个点关联。可以证明:最少的点(即覆盖数)=最大匹配数
    最大独立数:
    选取最多的点,使任意所选两点均不相连。
    最小路径覆盖数:
    对于一个 DAG(有向无环图),选取最少条数的路径,使得每个顶点属于且仅属于一条路径,路径长可以为 0(即单个点)。也就是说用尽量少的不相交简单路径覆盖DAG的所有结点。
    一些性质:
    定理1:最大匹配数=最小点覆盖数(Konig 定理)
    定理2:最大匹配数=最大独立数
    定理3:最小路径覆盖数=顶点数-最大匹配数

    匈牙利算法中的基本概念

    交替路:
    从一个未匹配的点出发,依次经过非匹配边、匹配边、非匹配边······这样形成的路径叫交替路。
    增广路:
    从一个未匹配的点出发,走交替路,如果路过一个未匹配的点(第一个点除外),这条交替路叫增广路。
    增广路有一个重要特点:非匹配边比匹配边多一条。因此,研究增广路的意义是改进匹配。只要把增广路中的匹配边和非匹配边的身份交换即可。由于中间的匹配节点不存在其他相连的匹配边,所以这样做不会破坏匹配的性质。交换后,图中的匹配边数目比原来多了 1 条。
    我们可以通过不停地找增广路来增加匹配中的匹配边和匹配点。找不到增广路时,达到最大匹配(这是增广路定理)。匈牙利算法正是这么做的,这也是算法的核心。

    匈牙利匹配算法

    论文:The Hungarian Method for the Assignment Problem
    论文地址:https://web.eecs.umich.edu/~pettie/matching/Kuhn-hungarian-assignment.pdf
    重要定理:
    如果从一个点A出发,没有找到增广路径,那么无论再从别的点出发找到多少增广路径来改变现在的匹配,从点A出发都永远找不到增广路径。
    匈牙利算法的核心思想:
    初始时最大匹配为控,然后不断寻找增广路,并扩展增广路。不断重复这一过程直到找不到增广路为止。
    如果二分图左半边U集合中共有n个点,那么最多找n条增广路径。如果图中共有m条边,那么每找一条增广路径(DFS或BFS)时最多把所有边遍历一遍,所花时间也就是m。所以总时间大概就是O(nm)。
    使用DFS查找的匈牙利匹配算法流程:
    从左边U集合找出第一个未匹配点(假设为点1)进行BFS边搜索,寻找一条未匹配边。如果找到一条未匹配边(假设为边1),这个边的另一头是右边V集合中的一个未匹配点(假设为点A),说明寻找成功。更新路径信息,匹配边数+1;
    再找到左边U集合的第二个未匹配点(假设为点2),进行BFS边搜索。假如搜索到一条边(假设为边2),该边连接的另一个点V集合中前一轮已经匹配的点(点A),那么我们将边2作为点2和点A的未匹配边,然后对放弃的未匹配边(边1)的另一个点(点1)重新进行BFS边搜索(这次搜索跳过已经选择过的边1),寻找另一条未匹配边。假设我们找到了新的一条为匹配边(边3),该边连接点1和点C。
    对于后面的每一轮,我们都从左边U集合中找出一个未匹配点x,然后进行BFS边搜索,如果搜到一条边,其另一点是V集合中前几轮中已经匹配的点y’,那么我们找到y’以前的未匹配边t,找到该边另一头属于左边U集合的点x’,对x’进行BFS边搜索(跳过前面已经选择的边),继续寻找未匹配边。如果x’BFS搜索到下一条边的另一点也是V集合中前几轮中已经匹配的点y’’,那么继续迭代执行上述过程。直到最后迭代找到的点的所有边都搜索过,且找不到为匹配边为止,此时我们就认为本轮最初选择的未匹配点x和点y’无法配对,我们不再从这个点x开始搜索。

    匈牙利匹配算法举例

    原始二分图中,集合U有点1、2、3、4,集合V中有点5、6、7、8,边有:1-5,1-6,2-5,3-6,3-8,4-7。

    1---5
     \ /
     / \
    2   6
       /
     /
    3   7
     \ /
     / \
    4   8  
    

    第一轮:
    选取集合U中未匹配点1,进行BFS边搜索,找到第一条边1-5,5是集合V中未匹配点,这样我们找到了一条边,将集合U的未匹配点1和集合V的未匹配点5配对,我们用link[5] = 1来表示。
    第二轮:
    接着选取集合U中未匹配的点2,进行BFS边搜索,找到第一条边2-5,但关于5这个点前面已经标记了一个配对边1-5,那么我们再对原来的点1继续进行BFS边搜索,发现另一条边1-6,6是集合V中未匹配点,于是将集合U的未匹配点1和集合V的未匹配点6配对,用link[6] = 1表示,此时link[5] = 1不变,但是要注意它此时的含义是点2和点5配对。
    第三轮:
    接着选取集合U中未匹配的点3,进行BFS边搜索,找到第一条边3-6,由于link[6] = 1,于是向前找到原来与6配对的点1,对点1再做BFS边搜索,发现边1-5,但点5已经和点2配对了。那么再对点2做BFS边搜索,发现2只有边2-5,搜索到头了只能停止。因此点3不能和点6配对。
    再找点3的第二条边,找到边3-8,8是集合V中未匹配点,这样我们将集合U的未匹配点3和集合V的未匹配点8配对,我们用link[8] = 1来表示。
    第四轮:
    接着选取集合U中未匹配点4,进行BFS边搜索,找到第一条边4-7,7是集合V中未匹配点,这样我们将集合U的未匹配点4和集合V的未匹配点7配对,我们用link[7] = 1来表示。

    这样我们就找到了这个二分图的最大匹配。最大匹配中包含的边是1-6,2-5,3-8,4-7。

    匈牙利匹配算法Python代码实现

    from collections import deque
    
    
    class HungarianAlgorithm(object):
    	def __init__(self, graph):
    		"""
    		这里的队列虽然用list也可以实现,但pop(0)的开销还是很大,因此还是用链式存储结构Deque
    		:param graph: 二分图的矩阵表示形式
    		"""
    		self.graph = graph
    		self.length = len(graph)
    
    	# x为输入的U集合中某个未匹配点,从V集合中寻找另一个未匹配点与其配对
    	def find(self, x):
    		for i in range(self.length):
    			# V集合中的点从第一个点开始遍历,如果两点之间有边且还没访问过V集合中这个点i
    			if self.graph[x][i] == 1 and not self.used[i]:
    				# 记录匹配边,放入交替路,记录V集合中的点i已访问过
    				self.used[i] = 1
    				# 如果点i之前已经访问过
    				# 如果V集合中的点i之前没有匹配过,或V集合中的点i之前匹配过,那么i的配对点为输入的x,x的配对点位i
    				if self.match[i] == -1 or self.find(self.match[i]) == 1:
    					# 那边令V集合的这个点匹配对象更新为x,
    					self.match[i] = x
    					self.match[x] = i
    					print(x + 1, '->', i + 1)
    					return 1
    		return 0
    
    	def hungarian1(self):
    		"""
    		递归形式的匈牙利匹配算法
    		:return:
    		"""
    		# 记录V集合中点的匹配情况的矩阵,一开始全初始化为-1,表示均未匹配
    		self.match = [-1] * self.length
    		# 记录是否访问过某个点(列表的某个元素,即矩阵的行向量)的矩阵,一开始全为False,表示全未访问过
    		self.used = [False] * self.length
    		m = 0
    		# 遍历所有U集合中的点(即列表的每个元素,每一个元素都是一个行向量,记录了这个U集合中的点与V集合中的哪些点有边)
    		for i in range(self.length):
    			# 如果U集合中第i个点还未匹配
    			if self.match[i] == -1:
    				# 令记录访问过的点记录的矩阵初始化,注意对U集合中每个未匹配点这个矩阵都要重新初始化一次
    				self.used = [False] * self.length
    				print("开始匹配U集合中第{}个点:".format(i + 1))
    				m += self.find(i)
    		# 返回的是最大匹配的边个数
    		return m
    
    	def hungarian2(self):
    		"""
    		循环形式的匈牙利匹配算法
    		:return:
    		"""
    		# 记录V集合中点的匹配情况的矩阵,一开始全初始化为-1,表示均未匹配
    		match = [-1] * self.length
    		# 记录是否访问过某个点(列表的某个元素,即矩阵的行向量)的矩阵,一开始全为False,表示全未访问过
    		used = [-1] * self.length
    		# 设置一个队列
    		q_list = deque()
    		# 记录最大匹配的边个数
    		ans = 0
    		# 代表上一个节点
    		prev = [0] * self.length
    		for i in range(self.length):
    			# 对U集合中第i个点,如果i还没有匹配过,清空队列,i假如队列
    			if match[i] == -1:
    				q_list.clear()
    				q_list.append(i)
    				# 设i为出发点
    				prev[i] = -1
    				# flag=False表示未找到增广路
    				flag = False
    				# 当队列不为空且还未找到增广路时
    				while len(q_list) > 0 and not flag:
    					# 队列左边出一个元素(即我们进队列的前面的点,最早进的点先出)
    					u = q_list.popleft()
    					# 查找V集合中的未匹配点
    					for j in range(self.length):
    						# 如果点U与V集合的点j有边且j的配对点不是i(即还未配对,或配对给其他点)
    						if not flag and self.graph[u][j] == 1 and used[j] != i:
    							# 配对
    							used[j] = i
    							# 如果u与j已经匹配过
    							if match[j] != -1:
    								# 把点j也加入队列
    								q_list.append(match[j])
    								# 记录点的顺序
    								prev[match[j]] = u
    							# 如果u与j没有匹配过,现在就开始匹配,且flag=True表示找到增广路
    							else:
    								flag = True
    								d = u
    								e = j
    								# 将原匹配的边去掉加入原来不在匹配中的边
    								while (d != -1):
    									t = match[d]
    									match[d] = e
    									match[e] = d
    									d = prev[d]
    									e = t
    								print('match:', match)
    								print('prev:', prev)
    								print('deque', q_list)
    				# 新增匹配边
    				if match[i] != -1:
    					ans += 1
    		# 返回的是最大匹配的边个数
    		return ans
    
    
    # 二分图用矩阵形式存储,即有多少行U集合中集有几个点,有多少列V集合中就有几个点
    # 两点之间如果有边则对应位置元素值为1(关于对角线对称)
    graph_1 = [(0, 0, 0, 0, 1, 0, 1, 0),
               (0, 0, 0, 0, 1, 0, 0, 0),
               (0, 0, 0, 0, 1, 1, 0, 0),
               (0, 0, 0, 0, 0, 0, 1, 1),
               (1, 1, 1, 0, 0, 0, 0, 0),
               (0, 0, 1, 0, 0, 0, 0, 0),
               (1, 0, 0, 1, 0, 0, 0, 0),
               (0, 0, 0, 1, 0, 0, 0, 0)]
    
    
    def do_hungarian1(graph):
    	h = HungarianAlgorithm(graph)
    	# print(h.graph)
    	# print(h.length)
    	print("最大匹配边数:{}".format(h.hungarian1()))
    
    
    def do_hungarian2(graph):
    	h = HungarianAlgorithm(graph)
    	# print(h.graph)
    	# print(h.length)
    	print("最大匹配边数:{}".format(h.hungarian2()))
    
    
    do_hungarian1(graph_1)
    do_hungarian2(graph_1)
    

    运行结果如下:

    
    开始匹配U集合中第1个点:
    1 -> 5
    开始匹配U集合中第2个点:
    1 -> 7
    2 -> 5
    开始匹配U集合中第3个点:
    3 -> 6
    开始匹配U集合中第4个点:
    4 -> 8
    最大匹配边数:4
    match: [4, -1, -1, -1, 0, -1, -1, -1]
    prev: [-1, 0, 0, 0, 0, 0, 0, 0]
    deque deque([])
    match: [6, 4, -1, -1, 1, -1, 0, -1]
    prev: [1, -1, 0, 0, 0, 0, 0, 0]
    deque deque([])
    match: [6, 4, 5, -1, 1, 2, 0, -1]
    prev: [1, 2, -1, 0, 0, 0, 0, 0]
    deque deque([1])
    match: [6, 4, 5, 7, 1, 2, 0, 3]
    prev: [3, 2, -1, -1, 0, 0, 0, 0]
    deque deque([0])
    最大匹配边数:4
    
    展开全文
  • 匈牙利匹配算法原理以及python实现

    千次阅读 2020-03-04 22:39:35
    【原创】我的KM算法详解 在Python中运行munkres库的复杂性 匈牙利算法和KM算法 匈牙利匹配的用法可以直接调用模块:(输出的结果不一样但都是最大匹配) from sklearn.utils.linear_assignment_ import linear_...

    原理可参考链接
    重:Munkres’ Assignment Algorithm Modified for Rectangular Matrices
    Munkres 分配算法
    Kuhn-Munkres 算法详细解析
    带你入门多目标跟踪(三)匈牙利算法&KM算法
    趣写算法系列之–匈牙利算法
    匈牙利算法维基百科
    【原创】我的KM算法详解
    在Python中运行munkres库的复杂性
    匈牙利算法和KM算法

    匈牙利匹配的用法可以直接调用模块:(输出的结果不一样但都是最大匹配)

    from sklearn.utils.linear_assignment_ import linear_assignment
    ## 法1:使用sklearn的模块
    cost_matrix = np.array([[147],[256],[671]) #这里自己定义
    indices = linear_assignment(cost_matrix)
    # indices 是一个n x 2的矩阵 对应代价矩阵的最大匹配的位置
    print(indices)
    
    
    ## 法2:使用scipy的模块
    from scipy.optimize import linear_sum_assignment
    row_ind, col_ind = linear_sum_assignment(cost_matrix)
    print([(x,y) for x,y in zip(row_ind,col_ind)])
    # row_ind,col为代价矩阵最佳匹配元素的行号和列号
    
    

    原理和源代码:

    [ 16 26 16 23 40 82 73 35 51 61 15 66 76 98 97 66 7 52 92 65 ] \left[ \begin{matrix} & 16 & 26 &16& 23& 40 \\ & 82& 73& 35& 51& 61 \\ & 15& 66& 76& 98& 97 \\ & 66& 7 &52& 92& 65 \\ \end{matrix} \right] 168215662673667163576522351989240619765

    [ 0 10 0 7 24 47 38 0 16 26 0 51 61 83 82 59 0 45 85 58 ] \left[ \begin{matrix} &0 &10 & 0 &7& 24\\ &47& 38& 0&16 &26 \\ &0& 51 &61& 83& 82\\ &59 & 0& 45& 85& 58\\ \end{matrix} \right] 0470591038510006145716838524268258

    marked:
    [ 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 ] \left[ \begin{matrix} &1 &0 &0& 0 &0 \\ &0& 0 &1 &0 &0\\ &0 &0 &0 &0& 0\\ &0 &1& 0 &0& 0\\ \end{matrix} \right] 10000001010000000000
    self.marked
    [[1 0 0 0 2],
    [0 0 1 0 0],
    [2 0 0 0 0],
    [0 1 0 0 0]]

    6 x 7 matrix

    原矩阵:
    [ 80 50 16 77 36 46 1 15 14 44 75 40 85 91 89 16 73 90 10 73 97 87 95 60 58 76 88 48 95 57 68 12 2 19 6 35 24 58 16 36 42 58 ] \left[ \begin{matrix} &80 &50&16&77&36&46& 1\\ &15 &14&44&75&40&85&91\\ & 89&16&73&90&10&73&97\\ &87&95&60&58& 76&88& 48\\ &95&57 &68 &12 &2& 19 & 6\\ &35&24&58 &16 &36 &42 &58\\ \end{matrix} \right] 801589879535501416955724164473606858777590581216364010762364685738819421919748658
    行归约:(对第一次匹配的标记一个1
    [ 79 49 15 76 35 45 0 1 1 0 1 30 61 26 71 77 79 6 63 80 0 1 63 87 39 47 12 10 28 40 0 93 55 66 10 0 17 4 19 8 42 0 1 20 26 42 ] \left[ \begin{matrix} &79& 49 &15 &76 &35& 45& \color{#00f} 0^1 \\ & 1 &\color{#00f}0^1& 30 &61&26& 71 &77\\ & 79& 6 &63& 80& \color{#00f}0^1& 63& 87\\ & 39& 47 &12& 10 &28& 40 & 0\\ & 93& 55& 66 &10 & 0& 17 &4\\ & 19& 8 &42 & \color{#00f}0^1& 20 &26& 42\\ \end{matrix} \right] 791793993194901647558153063126642766180101001352601280204571634017260177870442
    在这里插入图片描述
    self.marked
    [[0 0 0 0 0 0 1],
    [0 1 0 0 0 0 0],
    [0 0 0 0 1 0 0],
    [0 0 0 0 0 0 0],
    [0 0 0 0 0 0 0],
    [0 0 0 1 0 0 0]]
    列覆盖后没有0了
    减去最小值后(b,1)处为0标记为2
    [ 78 49 14 76 35 44 0 1 0 0 1 29 61 26 70 77 78 6 62 80 0 1 62 87 38 47 11 10 28 39 0 92 55 65 10 0 16 4 18 8 41 0 1 20 25 42 ] \left[ \begin{matrix} &78 &49 &14& 76& 35& 44&\color{#00f} 0^1\\ &0& \color{#00f}0^1& 29& 61& 26 &70& 77\\ & 78& 6& 62 &80 & \color{#00f}0^1& 62& 87\\ & 38& 47 &11& 10 &28& 39 & 0\\ & 92& 55 &65& 10& 0 &16 &4\\ & 18 &8 &41 &\color{#00f} 0^1& 20 &25& 42\\ \end{matrix} \right] 780783892184901647558142962116541766180101001352601280204470623916250177870442

    [ 78 49 14 76 35 44 0 1 0 2 0 1 29 61 26 70 77 78 6 62 80 0 1 62 87 38 47 11 10 28 39 0 92 55 65 10 0 16 4 18 8 41 0 1 20 25 42 ] \left[ \begin{matrix} &78 &49 &14& 76& 35& 44&\color{#00f} 0^1\\ &\color{#f00} 0^2 & \color{#00f}0^1& 29& 61& 26 &70& 77\\ & 78& 6& 62 &80 & \color{#00f}0^1& 62& 87\\ & 38& 47 &11& 10 &28& 39 & 0\\ & 92& 55 &65& 10& 0 &16 &4\\ & 18 &8 &41 &\color{#00f} 0^1& 20 &25& 42\\ \end{matrix} \right] 7802783892184901647558142962116541766180101001352601280204470623916250177870442
    在这里插入图片描述
    self.marked
    [[0 0 0 0 0 0 1],
    [2 1 0 0 0 0 0],
    [0 0 0 0 1 0 0],
    [0 0 0 0 0 0 0],
    [0 0 0 0 0 0 0],
    [0 0 0 1 0 0 0]]
    再减去最小值后
    [ 72 43 8 76 35 38 0 1 0 2 0 1 29 67 32 70 83 72 0 2 56 80 0 1 56 87 32 41 5 10 28 33 0 86 49 59 10 0 10 4 12 2 35 0 1 20 19 42 ] \left[ \begin{matrix} &72& 43 &8& 76 &35& 38& \color{#00f} 0^1\\ &\color{#f00} 0^2 & \color{#00f} 0^1& 29& 67& 32 &70& 83\\ & 72 &\color{#f00} 0^2& 56 &80& \color{#00f} 0^1& 56& 87\\ & 32& 41& 5 &10 &28& 33 & 0\\ & 86 &49& 59 &10 & 0& 10 & 4\\ & 12 & 2& 35& \color{#00f} 0^1 &20& 19 &42\\ \end{matrix} \right] 720272328612430102414928295655935766780101001353201280203870563310190183870442
    在这里插入图片描述
    self.marked
    [[0 0 0 0 0 0 1],
    [2 1 0 0 0 0 0],
    [0 2 0 0 1 0 0],
    [0 0 0 0 0 0 0],
    [0 0 0 0 0 0 0],
    [0 0 0 1 0 0 0]]

    将第5列置为true后第e,5出现新的0
    [ 72 43 8 76 35 38 0 1 0 2 0 1 29 67 32 70 83 72 0 2 56 80 0 1 56 87 32 41 5 10 28 33 0 86 49 59 10 0 2 10 4 12 2 35 0 1 20 19 42 ] \left[ \begin{matrix} &72& 43 &8& 76 &35& 38& \color{#00f} 0^1\\ &\color{#f00} 0^2 & \color{#00f} 0^1& 29& 67& 32 &70& 83\\ & 72 &\color{#f00} 0^2& 56 &80& \color{#00f} 0^1& 56& 87\\ & 32& 41& 5 &10 &28& 33 & 0\\ & 86 &49& 59 &10 &\color{#f00} 0^2& 10 & 4\\ & 12 & 2& 35& \color{#00f} 0^1 &20& 19 &42\\ \end{matrix} \right] 7202723286124301024149282956559357667801010013532012802203870563310190183870442
    增广路径:增广路径
    self.marked
    [[0 0 0 0 0 0 1],
    [2 1 0 0 0 0 0],
    [0 2 0 0 1 0 0],
    [0 0 0 0 0 0 0],
    [0 0 0 0 2 0 0],
    [0 0 0 1 0 0 0]]
    将增广路径取反,将路径上的1标记为0,路径上的2标记为1,清除覆盖
    [ 72 43 8 76 35 38 0 1 0 1 0 29 67 32 70 83 72 0 1 56 80 0 56 87 32 41 5 10 28 33 0 86 49 59 10 0 1 10 4 12 2 35 0 1 20 19 42 ] \left[ \begin{matrix} &72& 43 &8& 76 &35& 38& \color{#00f} 0^1\\ &\color{#00f} 0^1 & 0& 29& 67& 32 &70& 83\\ & 72 &\color{#00f} 0^1& 56 &80& 0& 56& 87\\ & 32& 41& 5 &10 &28& 33 & 0\\ & 86 &49& 59 &10 &\color{#00f} 0^1& 10 & 4\\ & 12 & 2& 35& \color{#00f} 0^1 &20& 19 &42\\ \end{matrix} \right] 72017232861243001414928295655935766780101001353202801203870563310190183870442
    [[0 0 0 0 0 0 1],
    [1 0 0 0 0 0 0],
    [0 1 0 0 0 0 0],
    [0 0 0 0 0 0 0],
    [0 0 0 0 1 0 0],
    [0 0 0 1 0 0 0]]
    只有5个匹配小于6,除了列覆盖以外减去最小值
    在这里插入图片描述
    [ 72 43 3 76 35 33 0 0 0 24 67 32 65 83 72 0 51 80 0 51 87 32 41 0 2 10 28 28 0 86 49 54 10 0 5 4 12 2 30 0 20 14 42 ] \left[ \begin{matrix} &72& 43 & 3& 76& 35& 33& 0\\ & 0 & 0 &24& 67 &32 &65& 83\\ & 72 & 0& 51 &80& 0& 51 &87\\ & 32& 41 & \color{#f00}0^2& 10& 28& 28 & 0 \\ & 86 &49 &54 &10& 0 &5 &4\\ & 12 & 2 &30 &0& 20& 14& 42\\ \end{matrix} \right] 720723286124300414923245102543076678010100353202802033655128514083870442

    self.marked
    [[0 0 0 0 0 0 1],
    [1 0 0 0 0 0 0],
    [0 1 0 0 0 0 0],
    [0 0 2 0 0 0 0],
    [0 0 0 0 1 0 0],
    [0 0 0 1 0 0 0]]
    进入step5修改2为1

    [ 72 43 3 76 35 33 0 1 0 1 0 24 67 32 65 83 72 0 1 51 80 0 51 87 32 41 0 1 10 28 28 0 86 49 54 10 0 1 5 4 12 2 30 0 1 20 14 42 ] \left[ \begin{matrix} &72& 43 & 3& 76& 35& 33& \color{#00f}0^1\\ & \color{#00f}0^1 & 0 &24& 67 &32 &65& 83\\ & 72 & \color{#00f}0^1& 51 &80& 0& 51 &87\\ & 32& 41 & \color{#00f}0^1& 10& 28& 28 & 0 \\ & 86 &49 &54 &10& \color{#00f}0^1 &5 &4\\ & 12 & 2 &30 &\color{#00f}0^1& 20& 14& 42\\ \end{matrix} \right] 72017232861243001414923245101543076678010100135320280120336551285140183870442

    [ 80 50 16 77 36 46 1 15 14 44 75 40 85 91 89 16 73 90 10 73 97 87 95 60 58 76 88 48 95 57 68 12 2 19 6 35 24 58 16 36 42 58 ] \left[ \begin{matrix} &80 &50&16&77&36&46& \color{#00f} 1\\ & \color{#00f}15 &14&44&75&40&85&91\\ & 89& \color{#00f}16&73&90&10&73&97\\ &87&95& \color{#00f}60&58& 76&88& 48\\ &95&57 &68 &12 & \color{#00f}2& 19 & 6\\ &35&24&58 & \color{#00f}16 &36 &42 &58\\ \end{matrix} \right] 801589879535501416955724164473606858777590581216364010762364685738819421919748658

    展开全文
  • 这时候我们想到了常见的多目标匹配算法:匈牙利算法和KM算法,因为匈牙利算法是没有带权重的,而我们这种场景很显然想要的就是谁离我更近我要谁,当然选用KM算法更为合适。 在这篇,先介绍匈牙利算法,有助于理解,...
  • 最近发现要写的东西很多,在轨迹规划中还有一大堆的新概念,但是要花大力气才能理解皮毛,所以调节一下,学点相对比较简单的概念,匈牙利匹配! 1.匈牙利匹配 匈牙利匹配最早是在图论中出现的,至于如何在自动...
  • 匈牙利匹配算法 摘要 匈牙利匹配算法可以用来做目标跟踪,根据预测算法预测box与上一帧box的iou关系可以确定是否是上一帧的目标。 也是比较常用的二分图匹配算法。 概念 图G的一个匹配是由一组没有公共端点的不是圈...
  • 1、卡尔曼滤波、 2、匈牙利匹配、 3、马氏距离、 4、欧氏距离、 5、级联匹配、 6、reid
  • 传统的数据关联方法多为运筹学方法,比较经典的即为匈牙利匹配算法和KM算法,接下来详细介绍这两种算法。 在介绍匈牙利匹配算法和KM算法之前,我们需要了解一个“二分图”的概念。简单来说就是,两组集合U和V,U和V...
  • 匈牙利匹配、KM算法 带你入门多目标跟踪(三)匈牙利算法&KM算法 - 知乎 卡尔曼滤波: 图像处理之目标跟踪(一)之卡尔曼kalman滤波跟踪(主要为知识梳理)(转载)_coming_is_winter的博客-CSDN博客_卡尔曼滤波跟踪...
  • matlab实现匈牙利算法二分图最大匹配的程序
  • 下面我给出我的卡尔曼滤波之后的匈牙利匹配算法的代码 ''' File name : tracker.py File Description : Tracker Using Kalman Filter & Hungarian Algorithm Date created : 07/14/2017 Date last modified: ...
  • 匈牙利匹配算法介绍

    2021-12-29 22:53:41
    二分图 待更新。。。
  • HDU3605 匈牙利匹配

    2016-11-06 15:11:34
    各种循环优化,外加一个前驱记录,匈牙利匹配的运用。 #include #include #include using namespace std; int n, m; int line[100002][12]; bool used[12]; int girl[12]; int ok[12][100002]; int cnt[12]; ...
  • 匈牙利算法解决了分配问题,定义如下: 有许多代理和许多任务。 可以分配任何座席以执行任何任务,这会产生一些费用,该费用可能会因座席任务分配而异。 要求执行所有任务,方法是将每个任务恰好分配给一个代理,将...
  • from scipy.optimize import linear_sum_assignment indx_1, indx_2 = linear_sum_assignment(-matric)
  • 后来通过实习和查阅论文等渠道了解到了多目标跟踪领域经典的Sort和DeepSort算法,其中都使用到了匈牙利算法解决匹配问题,因此开此贴记录一下算法的学习过程。 指派问题概述 首先,对匈牙利算法解决的问题进行概述:...
  • ACM学习-匈牙利匹配

    2015-08-29 10:42:35
    匈牙利匹配先说一种简单情况,多了也是一样,比如A,B,C找对象,一开始A问B有没有对象,B说没有,OK,A告诉B以后你的对象是我,如果C也开始在周围(相连的节点)找对象,假如找到B,发现B已经有对象,就问B你周围有人...
  • 最后就是朴素的匈牙利匹配算法了:首先1-2成功,2匹配5成功,3匹配5的时候不成功,但是我们我们可以将集合y中5的x集合中 的匹配元素2在找一个匹配正好找到y集合中的6,所以问题中的最大匹配是3 这一到题目就是...
  • 在讲将匈牙利算法解决任务分配问题之前,先分析几个具体实例。 以3个工作人员和3项任务为实例,下图为薪酬图表和根据薪酬图表所得的cost矩阵。   利用最简单的方法(全排列法)进行求解,计算出所有分配情况的总...
  • 在一个匹配的基础上,我们可以扩大匹配(这个就是匈牙利算法的精髓,一会讲),当扩大到最大,我们就说这是一个极大匹配。 最大匹配 在极大匹配中,有的匹配边数会比其他的多一点,所以我们把最大的叫做最大匹配。 ...
  • 匈牙利算法几乎是二分图匹配的核心算法,除了二分图多重匹配外均可使用 匈牙利算法实际上就是一种网络流的思想,其核心就是寻找增广路。具体操作就是嗯。。拉郎配 匈牙利算法适用的场合: 二分图匹配 链上的...
  • 什么是匹配 匹配:在图论中,一个「匹配」是一个边的集合,其中任意两条边都没有公共顶点。 最大匹配:一个图所有匹配中,所含匹配边数最多的...匈牙利算法就是在是二分图的基础上,求二分图的最大匹配的算法。 二分图
  • 二分图完全匹配算法之匈牙利算法

    千次阅读 2022-01-30 17:57:25
    最近在参加了一个小项目,里面用到二分图匹配算法,因为之前并没有接触过相关算法,于是找到一些博客进行了一番学习,但学习之后,发现部分博客或多或少存在一些另我疑惑的地方,于是,我打算写此博客以巩固对算法的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 17,723
精华内容 7,089
关键字:

匈牙利匹配

友情链接: magetic bearing simu.rar