@@ -1583,126 +1583,126 @@ function(gr)
1583
1583
return fail ;
1584
1584
end );
1585
1585
1586
- InstallMethod(VertexConnectivity,
1587
- " for a digraph" ,
1588
- [ IsDigraph] ,
1586
+ InstallMethod(VertexConnectivity, " for a digraph" , [ IsDigraph] ,
1589
1587
function (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;
1592
1589
1593
1590
if DigraphNrVertices(digraph) <= 1 or not IsConnectedDigraph(digraph) then
1594
1591
return 0 ;
1595
1592
fi ;
1596
1593
1597
1594
if IsMultiDigraph(digraph) then
1598
- sdigraph := DigraphRemoveAllMultipleEdges(digraph);
1599
- else
1600
- sdigraph := digraph;
1595
+ digraph := DigraphRemoveAllMultipleEdges(digraph);
1601
1596
fi ;
1602
1597
1603
1598
kappas := [ DigraphNrVertices(digraph) - 1 ] ;
1604
1599
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 ;
1630
1611
fi ;
1631
- end ;
1632
-
1633
- lst := [ 0 , 0 , 0 , 0 ] ;
1634
- for x in [ 1 .. Size(outn)] do
1635
- decide(x, 1 );
1636
1612
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 ;
1640
1623
od ;
1641
1624
od ;
1625
+ return List(mat, x -> ListBlist([ 1 .. 2 * n] , x));
1626
+ end ;
1642
1627
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;
1648
1634
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 ;
1655
1635
flow := 0 ;
1656
1636
capacity := List(netw, x -> BlistList(x, x));
1637
+ nredges := Sum(List(netw, Length));
1657
1638
1658
- while flag do
1659
- queue := [ 1 ] ;
1639
+ while true do
1640
+ queue := [ source] ;
1641
+ m := 1 ;
1660
1642
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
1664
1646
current := queue[ m] ;
1665
-
1666
1647
n := 0 ;
1667
- for e in netw[ current] do
1648
+ for v in netw[ current] do
1668
1649
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 ;
1672
1658
fi ;
1673
1659
od ;
1674
1660
m := m + 1 ;
1675
1661
od ;
1676
1662
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] ;
1682
1670
od ;
1683
1671
flow := flow + 1 ;
1684
1672
else
1685
- flag := false ;
1673
+ return flow ;
1686
1674
fi ;
1687
1675
od ;
1688
- return flow;
1689
1676
end ;
1690
1677
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);
1705
1702
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);
1706
1706
if k = 0 then
1707
1707
return 0 ;
1708
1708
else
@@ -1713,9 +1713,8 @@ function(digraph)
1713
1713
1714
1714
for x in [ 1 .. Size(Nv) - 1 ] do
1715
1715
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] );
1719
1718
if k = 0 then
1720
1719
return 0 ;
1721
1720
else
0 commit comments