@@ -1583,126 +1583,126 @@ function(gr)
15831583 return fail ;
15841584end );
15851585
1586- InstallMethod(VertexConnectivity,
1587- " for a digraph" ,
1588- [ IsDigraph] ,
1586+ InstallMethod(VertexConnectivity, " for a digraph" , [ IsDigraph] ,
15891587function (digraph )
1590- local degs, edges, edmondskarp, indegs, k, kappas, mindegv, newnetw, Nv,
1591- outdegs, outn, sdigraph, set1v, x, y;
1588+ local kappas, newnetw, edmondskarp, mat, degs, mindegv, mindeg, Nv, outn, k, i, j, x, y;
15921589
15931590 if DigraphNrVertices(digraph) <= 1 or not IsConnectedDigraph(digraph) then
15941591 return 0 ;
15951592 fi ;
15961593
15971594 if IsMultiDigraph(digraph) then
1598- sdigraph := DigraphRemoveAllMultipleEdges(digraph);
1599- else
1600- sdigraph := digraph;
1595+ digraph := DigraphRemoveAllMultipleEdges(digraph);
16011596 fi ;
16021597
16031598 kappas := [ DigraphNrVertices(digraph) - 1 ] ;
16041599
1605- # The function newnetw is an implementation of Algorithm Nine from Abdol-Hossein
1606- # Esfahanian's ``Connectivity Algorithms'' which can be found at
1607- # https://www.cse.msu.edu/~cse835/Papers/Graph_connectivity_revised.pdf
1608- newnetw := function (source, sink )
1609- local decide, lst, noutn, x, y;
1610- noutn := List([ 1 .. (Size(outn) - 2 ) * 2 + 2 ] , x -> [] );
1611-
1612- decide := function (p, q )
1613- local cor;
1614- cor := (q - 1 ) * 2 + 1 ;
1615- if p = source then
1616- lst{[ cor, cor + 1 ]} := [ 1 , 1 ] ;
1617- elif p = sink then
1618- lst{[ cor, cor + 1 ]} := [ 2 , 2 ] ;
1619- else
1620- if p > source or p > sink then
1621- if p > source and p > sink then
1622- lst[ cor] := (p - 2 ) * 2 + q;
1623- else
1624- lst[ cor] := (p - 1 ) * 2 + q;
1625- fi ;
1626- else
1627- lst[ cor] := p * 2 + q;
1628- fi ;
1629- lst[ cor + 1 ] := lst[ cor] + 1 * (- 1 ) ^ (q + 1 );
1600+ # The function newnetw is an implementation of Algorithm Nine from Abdol-Hossein
1601+ # Esfahanian's ``Connectivity Algorithms'' which can be found at
1602+ # https://www.cse.msu.edu/~cse835/Papers/Graph_connectivity_revised.pdf
1603+ newnetw := function (digraph, source, sink )
1604+ local n, mat, outn, x, y;
1605+ n := DigraphNrVertices(digraph);
1606+ mat := List([ 1 .. 2 * n] , x -> BlistList([ 1 .. 2 * n] , [] ));
1607+ outn := OutNeighbours(digraph);
1608+ for x in [ 1 .. DigraphNrVertices(digraph)] do
1609+ if x <> source and x <> sink then
1610+ mat[ x + n][ x] := true ;
16301611 fi ;
1631- end ;
1632-
1633- lst := [ 0 , 0 , 0 , 0 ] ;
1634- for x in [ 1 .. Size(outn)] do
1635- decide(x, 1 );
16361612 for y in outn[ x] do
1637- decide(y, 2 );
1638- AddSet(noutn[ lst[ 1 ]] , lst[ 3 ] );
1639- AddSet(noutn[ lst[ 4 ]] , lst[ 2 ] );
1613+ if x = source or x = sink then
1614+ mat[ x][ y + n] := true ;
1615+ mat[ y][ x] := true ;
1616+ elif y = source or y = sink then
1617+ mat[ y][ x + n] := true ;
1618+ mat[ x][ y] := true ;
1619+ else
1620+ mat[ y][ x + n] := true ;
1621+ mat[ x][ y + n] := true ;
1622+ fi ;
16401623 od ;
16411624 od ;
1625+ return List(mat, x -> ListBlist([ 1 .. 2 * n] , x));
1626+ end ;
16421627
1643- for x in [ 1 .. Size(outn) - 2 ] do
1644- Add(noutn[ x * 2 + 2 ] , x * 2 + 1 );
1645- od ;
1646- return noutn;
1647- end ;
1628+ # The following function is an implementation of the Edmonds-Karp algorithm with
1629+ # some minor adjustments that take into account the fact that the capacity of
1630+ # all edges is 1.
1631+ edmondskarp := function (netw, source, sink )
1632+ local flow, capacity, nredges, queue, m, predecessor, edgeindex, stop,
1633+ current, n, v;
16481634
1649- # The following function is an implementation of the Edmonds-Karp algorithm with
1650- # some minor adjustments that take into account the fact that the capacity of
1651- # all edges is 1.
1652- edmondskarp := function (netw )
1653- local capacity, current, e, flag, flow, m, n, predecessor, queue;
1654- flag := true ;
16551635 flow := 0 ;
16561636 capacity := List(netw, x -> BlistList(x, x));
1637+ nredges := Sum(List(netw, Length));
16571638
1658- while flag do
1659- queue := [ 1 ] ;
1639+ while true do
1640+ queue := [ source] ;
1641+ m := 1 ;
16601642 predecessor := List(netw, x -> 0 );
1661-
1662- m := 1 ;
1663- while m <= Size(queue) do
1643+ edgeindex := List(netw, x -> 0 );
1644+ stop := false ;
1645+ while m <= Size(queue) and not stop do
16641646 current := queue[ m] ;
1665-
16661647 n := 0 ;
1667- for e in netw[ current] do
1648+ for v in netw[ current] do
16681649 n := n + 1 ;
1669- if predecessor[ e] = 0 and e <> 1 and capacity[ current][ n] then
1670- predecessor[ e] := [ current, n] ;
1671- Add(queue, e);
1650+ if predecessor[ v] = 0 and v <> source and capacity[ current][ n] then
1651+ predecessor[ v] := current;
1652+ edgeindex[ v] := n;
1653+ Add(queue, v);
1654+ fi ;
1655+ if v = sink then
1656+ stop := true ;
1657+ break ;
16721658 fi ;
16731659 od ;
16741660 m := m + 1 ;
16751661 od ;
16761662
1677- if predecessor[ 2 ] <> 0 then
1678- e := predecessor[ 2 ] ;
1679- while e <> 0 do
1680- capacity[ e[ 1 ]][ e[ 2 ]] := false ;
1681- e := predecessor[ e[ 1 ]] ;
1663+ if predecessor[ sink] <> 0 then
1664+ v := predecessor[ sink] ;
1665+ n := edgeindex[ sink] ;
1666+ while v <> 0 do
1667+ capacity[ v][ n] := false ;
1668+ n := edgeindex[ v] ;
1669+ v := predecessor[ v] ;
16821670 od ;
16831671 flow := flow + 1 ;
16841672 else
1685- flag := false ;
1673+ return flow ;
16861674 fi ;
16871675 od ;
1688- return flow;
16891676 end ;
16901677
1691- # Referring once again to Abdol-Hossein Esfahanian's paper (see newnetw, above)
1692- # the following lines implement Algorithm Eleven of that paper.
1693- outdegs := OutDegrees(sdigraph);
1694- indegs := InDegrees(sdigraph);
1695- degs := List([ 1 .. Size(outdegs)] , x -> Maximum(outdegs[ x] , indegs[ x] ));
1696- mindegv := Position(degs, Minimum(degs));
1697- set1v := ShallowCopy(DigraphVertices(sdigraph));
1698- Remove(set1v, mindegv);
1699- Nv := OutNeighboursOfVertex(sdigraph, mindegv);
1700- outn := OutNeighbours(sdigraph);
1701-
1702- for x in set1v do
1703- if not x in outn[ mindegv] and not mindegv in outn[ x] then
1704- k := edmondskarp(newnetw(mindegv, x));
1678+ # Referring once again to Abdol-Hossein Esfahanian's paper (see newnetw, above)
1679+ # the following lines implement Algorithm Eleven of that paper.
1680+ mat := BooleanAdjacencyMatrix(digraph);
1681+ degs := ListWithIdenticalEntries(DigraphNrVertices(digraph), 0 );
1682+ for i in DigraphVertices(digraph) do
1683+ for j in [ i + 1 .. DigraphNrVertices(digraph)] do
1684+ if mat[ i][ j] or mat[ j][ i] then
1685+ degs[ i] := degs[ i] + 1 ;
1686+ degs[ j] := degs[ j] + 1 ;
1687+ fi ;
1688+ od ;
1689+ od ;
1690+
1691+ mindegv := 0 ;
1692+ mindeg := DigraphNrVertices(digraph) + 1 ;
1693+ for i in DigraphVertices(digraph) do
1694+ if degs[ i] < mindeg then
1695+ mindeg := degs[ i] ;
1696+ mindegv := i;
1697+ fi ;
1698+ od ;
1699+
1700+ Nv := OutNeighboursOfVertex(digraph, mindegv);
1701+ outn := OutNeighbours(digraph);
17051702
1703+ for x in DigraphVertices(digraph) do
1704+ if x <> mindegv and not mat[ x][ mindegv] and not mat[ mindegv][ x] then
1705+ k := edmondskarp(newnetw(digraph, mindegv, x), mindegv, x);
17061706 if k = 0 then
17071707 return 0 ;
17081708 else
@@ -1713,9 +1713,8 @@ function(digraph)
17131713
17141714 for x in [ 1 .. Size(Nv) - 1 ] do
17151715 for y in [ x + 1 .. Size(Nv)] do
1716- if not Nv[ y] in outn[ Nv[ x]] and not Nv[ x] in outn[ Nv[ y]] then
1717- k := edmondskarp(newnetw(Nv[ x] , Nv[ y] ));
1718-
1716+ if not mat[ Nv[ x]][ Nv[ y]] and not mat[ Nv[ y]][ Nv[ x]] then
1717+ k := edmondskarp(newnetw(digraph, Nv[ x] , Nv[ y] ), Nv[ x] , Nv[ y] );
17191718 if k = 0 then
17201719 return 0 ;
17211720 else
0 commit comments