• 匹配算法匈牙利算法简介


    今天一直在查找匹配算法之类的问题,现在正好有机会和大家分享一下.

        一、二分图的匹配

        匈牙利算法是用来求二分图匹配用的,体具的问题网上都有,这里不再重复。

        二、匈牙利算法及其实现

        先定义一些观点吧:

        (1)、匹配:二分图中的匹配,就是边左的点所对应边右的点的那条边的合集

        (2)、匹配边:在匹配合集中的边

        (3)、未匹配点:义思名顾,就是不是匹配边的端点的点(网上写的是未盖点,但我以为写未匹配点更轻易懂得)

        (4)、错交轨:就是一条在二分图中的路径,这条路径是由匹配边、未匹配边成构的(注意:这里与点是没有关系的

        (5)、增广路:点起与终点都是未匹配点的错交轨

        我们可以演绎出如下定理或者说是定理:

        (1)、当一个二分图有最大匹配时当且仅当它不存在增广路径

        (2)、一条增广路径所包括的边数必为奇数,且未匹配边比匹配边多一条

        (3)、增广路上的第一条边和最后一条边都不是匹配边,增广路的两个顶点分离落在二分图的两个分部中

        (4)、设p为一条包括匹配边的增广路径,那么对增广路上的所有边停止取反操纵,那么就能够到得一个比本来多1的匹配(定理2)

        (5)、主要又不主要的定理:在增广路中,从未匹配点开始,从边左到边右定一是未匹配边,从边右到边左定一是匹配边(这个论结对于大分部论文的懂得都用有)

        面上的定理定一先要懂得,不要过量的纠结于明证,不懂的可以画图画,然后对应的找出个每观点所对应的货色,然后继承:

        由于有了定理4,所以我们可以到得一个基本的算法:对一个图一直的找寻增广路,直到找不到增广路为止,可以明证,当没有增广路时,二分图中定一存在最大匹配——这就是匈牙利算法!!!

        然后就是算法的实现了,可能大分部人看了面上的算法后之都市发生怎么实现的疑难,网上的很多论文都没有讲清楚,面下我谈谈我个人的懂得:

        (1)、为了叙说的便利,我们先把二分图划分为两个合集,边左为L合集,边右为R合集

        (2)、由于匈牙利算法的核心分部是从一个点动身,看看有没有增广路,所以我只在这里叙说如何断判从一个顶点动身有没有增广路

        每日一道理
    记不清有多少个夜晚,在我翻阅纸张的指间滑落;记不清有多少支蜡烛,在我的凝视中化为灰烬。逝者如斯,我时时刻刻会听见自己对生命承诺的余音,感到岁月的流转在渐渐稀释我的年少无知,我愿自己是一只上足了发条的时钟,在昼夜不停的流转中留下自己充实的每一刻。

        (3)、设我们动身的点为X(X∈L),然后我们从搜索与X相连接的,不在增广路中的点Y(Y∈R)注意:1、如果在增广路中则说明我们之前经已搜索过该点 2、由定理3,此时X->Y为未匹配边),然后我们看看Y是不是未匹配点(如果是未匹配点,那么我们当然可以直接把X->Y看作是增广路,此时我们从X搜索增广路毕完,搜索结果是增广路只包括X->Y一条边),如果是匹配点,那么我们设H匹配Y(H∈X),然后我们看从H动身有没有增广路(如果从H动身有增广路,那么我们可以把Y连到X了,因原是:1、X->Y是未匹配边 2、从H动身有增广路,由于Y->H是在增广路中的,而且由于定理5(这里我们把定理5看作已知件条),Y->H是匹配边,合结因原1,我们可以得出:[X->Y->H+H的增广路]定一也是也是增广路,此时找到增广路后就能够直接退出了,因为我们的的目只是要找寻一条增广路,而不是最长的增广路

        不知道面上的货色各位有没有看懂,没有看懂的可以给我发Email:hncsyjc@163.com

        于是序程就出来了,面下附上HDU 2063的代码,这是一道裸题,直接用匈牙利算法就能够做了。

        

    var
            n,m,k,i,j,ans,x,y:longint;
            l:array [1..510,1..510] of boolean;
            v:array [1..510] of boolean;
            p:array [1..510] of longint;
    function find(x:longint):boolean;//从x开始有没有增广路
    var
            i:longint;
    begin
            for i:=1 to m do
              if (l[x,i])and(not v[i]) then begin
                v[i]:=true;
                if (p[i]=0)or(find(p[i])) then begin //如果i是未匹配点或者从i的对应点可以找到增广路
                  p[i]:=x;  //与i的对应点
                  exit(true);
                end;
              end;
            exit(false);
    end;
    begin
            repeat
              read(k);
              if k=0 then break;
              readln(n,m);
              fillchar(l,sizeof(l),false);
              fillchar(p,sizeof(p),0);
              ans:=0;
              for i:=1 to k do
              begin
                readln(x,y);l[x,y]:=true;
              end;
              for i:=1 to n do //匈牙利的第二个主过程
              begin
                fillchar(v,sizeof(v),false);
                if find(i) then inc(ans);
              end;
              writeln(ans);
            until false;
    end.

        匈牙利算法,关键是思想

        Hncsyjc

        转载请注明来源

    文章结束给大家分享下程序员的一些笑话语录: 这年头的互联网真是娱乐了中国,网民们从各种各样的“门”里钻来钻去,又有好多“哥”好多“帝”,值得大家品味不已……网络经典语录,关于IT与互联网,经典与您分享!

  • 相关阅读:
    第一阶段-意见评论
    团队冲刺第15天
    团队冲刺第14天
    第十三周进度报告
    团队冲刺第13天
    团队冲刺第12天
    团队冲刺第11天
    SCRUM第二阶段第九天
    SCRUM第二阶段第八天
    SCRUM第二阶段第七天
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3050676.html
Copyright © 2020-2023  润新知