@@ -2044,3 +2044,237 @@ InstallMethod(DigraphMycielskian,
20442044
20452045InstallMethod(DigraphMycielskianAttr, " for an immutable digraph" ,
20462046[ IsImmutableDigraph] , DigraphMycielskian);
2047+
2048+ # Uses a simple greedy algorithm.
2049+ BindGlobal(" DIGRAPHS_MaximalMatching" ,
2050+ function (D )
2051+ local mate, u, v;
2052+ mate := ListWithIdenticalEntries(DigraphNrVertices(D), 0 );
2053+ for v in DigraphVertices(D) do
2054+ if mate[ v] = 0 then
2055+ for u in OutNeighboursOfVertex(D, v) do
2056+ if mate[ u] = 0 then
2057+ mate[ u] := v;
2058+ mate[ v] := u;
2059+ break ;
2060+ fi ;
2061+ od ;
2062+ fi ;
2063+ od ;
2064+ return mate;
2065+ end );
2066+
2067+ # For bipartite digraphs implements the Hopcroft-Karp matching algorithm,
2068+ # complexity O(m*sqrt(n))
2069+ BindGlobal(" DIGRAPHS_BipartiteMatching" ,
2070+ function (D, mate )
2071+ local U, dist, inf, dfs, bfs, u;
2072+
2073+ U := DigraphBicomponents(D);
2074+ U := U[ PositionMinimum(U, Length)] ;
2075+
2076+ bfs := function ()
2077+ local v, que, q;
2078+ que := [] ;
2079+ for v in U do
2080+ if mate[ v] = inf then
2081+ dist[ v] := 0 ;
2082+ Add(que, v);
2083+ else
2084+ dist[ v] := inf;
2085+ fi ;
2086+ od ;
2087+ dist[ inf] := inf;
2088+
2089+ q := 1 ;
2090+ while q <= Length(que) do
2091+ if dist[ que[ q]] < dist[ inf] then
2092+ for v in OutNeighborsOfVertex(D, que[ q] ) do
2093+ if dist[ mate[ v]] = inf then
2094+ dist[ mate[ v]] := dist[ que[ q]] + 1 ;
2095+ Add(que, mate[ v] );
2096+ fi ;
2097+ od ;
2098+ fi ;
2099+ q := q + 1 ;
2100+ od ;
2101+ return dist[ inf] <> inf;
2102+ end ;
2103+
2104+ dfs := function (u )
2105+ local v;
2106+ if u = inf then
2107+ return true ;
2108+ fi ;
2109+ for v in OutNeighborsOfVertex(D, u) do
2110+ if dist[ mate[ v]] = dist[ u] + 1 and dfs(mate[ v] ) then
2111+ mate[ v] := u;
2112+ mate[ u] := v;
2113+ return true ;
2114+ fi ;
2115+ od ;
2116+ dist[ u] := inf;
2117+ return false ;
2118+ end ;
2119+
2120+ inf := DigraphNrVertices(D) + 1 ;
2121+ dist := ListWithIdenticalEntries(inf, inf);
2122+ for u in [ 1 .. Length(mate)] do
2123+ if mate[ u] = 0 then
2124+ mate[ u] := inf;
2125+ fi ;
2126+ od ;
2127+
2128+ while bfs() do
2129+ for u in U do
2130+ if mate[ u] = inf then dfs(u);
2131+ fi ;
2132+ od ;
2133+ od ;
2134+
2135+ for u in [ 1 .. DigraphNrVertices(D)] do
2136+ if mate[ u] = inf then
2137+ mate[ u] := 0 ;
2138+ fi ;
2139+ od ;
2140+
2141+ return mate;
2142+ end );
2143+
2144+ # For general digraphs implements a modified version of Gabow's maximum matching
2145+ # algorithm, complexity O(m*n*log(n)).
2146+ BindGlobal(" DIGRAPHS_GeneralMatching" ,
2147+ function (D, mate )
2148+ local blos, pred, time, t, tj, u, dfs, mark, blosfind;
2149+
2150+ blosfind := function (x )
2151+ if x <> blos[ x] then
2152+ blos[ x] := blosfind(blos[ x] );
2153+ fi ;
2154+ return blos[ x] ;
2155+ end ;
2156+
2157+ mark := function (v, x, b, path )
2158+ while blosfind(v) <> b do
2159+ pred[ v] := x;
2160+ x := mate[ v] ;
2161+ Add(tj, v);
2162+ Add(tj, x);
2163+ if time[ x] = 0 then
2164+ t := t + 1 ;
2165+ time[ x] := t;
2166+ Add(path, x);
2167+ fi ;
2168+ v := pred[ x] ;
2169+ od ;
2170+ end ;
2171+
2172+ dfs := function (v )
2173+ local x, bx, bv, b, y, z, path;
2174+ for x in OutNeighboursOfVertex(D, v) do
2175+ bv := blosfind(v);
2176+ bx := blosfind(x);
2177+ if bx <> bv then
2178+ if time[ x] > 0 then
2179+ path := [] ;
2180+ tj := [] ;
2181+ if time[ bx] < time[ bv] then
2182+ b := bx;
2183+ mark(v, x, b, path);
2184+ else
2185+ b := bv;
2186+ mark(x, v, b, path);
2187+ fi ;
2188+ for z in tj do
2189+ blos[ z] := b;
2190+ od ;
2191+ for z in path do
2192+ if dfs(z) then
2193+ return true ;
2194+ fi ;
2195+ od ;
2196+ elif pred[ x] = 0 then
2197+ pred[ x] := v;
2198+ if mate[ x] = 0 then
2199+ while x <> 0 do
2200+ y := pred[ x] ;
2201+ v := mate[ y] ;
2202+ mate[ y] := x;
2203+ mate[ x] := y;
2204+ x := v;
2205+ od ;
2206+ return true ;
2207+ fi ;
2208+ if time[ mate[ x]] = 0 then
2209+ t := t + 1 ;
2210+ time[ mate[ x]] := t;
2211+ if dfs(mate[ x] ) then
2212+ return true ;
2213+ fi ;
2214+ fi ;
2215+ fi ;
2216+ fi ;
2217+ od ;
2218+ return false ;
2219+ end ;
2220+
2221+ time := ListWithIdenticalEntries(DigraphNrVertices(D), 0 );
2222+ blos := [ 1 .. DigraphNrVertices(D)] ;
2223+ pred := ListWithIdenticalEntries(DigraphNrVertices(D), 0 );
2224+ t := 0 ;
2225+ for u in DigraphVertices(D) do
2226+ if mate[ u] = 0 then
2227+ t := t + 1 ;
2228+ time[ u] := t;
2229+ if dfs(u) then
2230+ time := ListWithIdenticalEntries(DigraphNrVertices(D), 0 );
2231+ blos := [ 1 .. DigraphNrVertices(D)] ;
2232+ pred := ListWithIdenticalEntries(DigraphNrVertices(D), 0 );
2233+ fi ;
2234+ fi ;
2235+ od ;
2236+
2237+ return mate;
2238+ end );
2239+
2240+ BindGlobal(" DIGRAPHS_MateToMatching" ,
2241+ function (D, mate )
2242+ local u, M;
2243+ M := [] ;
2244+ for u in DigraphVertices(D) do
2245+ if u <= mate[ u] then
2246+ if IsDigraphEdge(D, u, mate[ u] ) then
2247+ Add(M, [ u, mate[ u]] );
2248+ elif IsDigraphEdge(D, mate[ u] , u) then
2249+ Add(M, [ mate[ u] , u] );
2250+ fi ;
2251+ fi ;
2252+ od ;
2253+ return Set(M);
2254+ end );
2255+
2256+ InstallMethod(DigraphMaximalMatching, " for a digraph" , [ IsDigraph] ,
2257+ D -> DIGRAPHS_MateToMatching(D, DIGRAPHS_MaximalMatching(D)));
2258+
2259+ InstallMethod(DigraphMaximumMatching, " for a digraph" , [ IsDigraph] ,
2260+ function (D )
2261+ local mateG, mateD, G, M, i, lab;
2262+ G := DigraphImmutableCopy(D);
2263+ G := InducedSubdigraph(G, Difference(DigraphVertices(G), DigraphLoops(G)));
2264+ lab := DigraphVertexLabels(G);
2265+ G := DigraphSymmetricClosure(G);
2266+ mateG := DIGRAPHS_MaximalMatching(G);
2267+ if IsBipartiteDigraph(G) then
2268+ mateG := DIGRAPHS_BipartiteMatching(G, mateG);
2269+ else
2270+ mateG := DIGRAPHS_GeneralMatching(G, mateG);
2271+ fi ;
2272+ mateD := ListWithIdenticalEntries(DigraphNrVertices(D), 0 );
2273+ for i in DigraphVertices(G) do
2274+ if mateG[ i] <> 0 then
2275+ mateD[ lab[ i]] := lab[ mateG[ i]] ;
2276+ fi ;
2277+ od ;
2278+ M := List(DigraphLoops(D), x -> [ x, x] );
2279+ return Union(M, DIGRAPHS_MateToMatching(D, mateD));
2280+ end );
0 commit comments