@@ -2613,3 +2613,146 @@ function(D)
2613
2613
M := List(DigraphLoops(D), x -> [ x, x] );
2614
2614
return Union(M, DIGRAPHS_MateToMatching(D, mateD));
2615
2615
end );
2616
+
2617
+ InstallMethod(VertexConnectivity, " for a digraph" , [ IsDigraph] ,
2618
+ function (digraph )
2619
+ local kappas, newnetw, edmondskarp, mat, degs, mindegv, mindeg, Nv, outn, k,
2620
+ i, j, x, y;
2621
+
2622
+ if DigraphNrVertices(digraph) <= 1 or not IsConnectedDigraph(digraph) then
2623
+ return 0 ;
2624
+ fi ;
2625
+
2626
+ if IsMultiDigraph(digraph) then
2627
+ digraph := DigraphRemoveAllMultipleEdges(digraph);
2628
+ fi ;
2629
+
2630
+ kappas := [ DigraphNrVertices(digraph) - 1 ] ;
2631
+
2632
+ # The function newnetw is an implementation of Algorithm Nine from
2633
+ # Abdol-Hossein Esfahanian's ``Connectivity Algorithms'' which can be found at
2634
+ # https://www.cse.msu.edu/~cse835/Papers/Graph_connectivity_revised.pdf
2635
+ newnetw := function (digraph, source, sink )
2636
+ local n, mat, outn, x, y;
2637
+ n := DigraphNrVertices(digraph);
2638
+ mat := List([ 1 .. 2 * n] , x -> BlistList([ 1 .. 2 * n] , [] ));
2639
+ outn := OutNeighbours(digraph);
2640
+ for x in [ 1 .. DigraphNrVertices(digraph)] do
2641
+ if x <> source and x <> sink then
2642
+ mat[ x + n][ x] := true ;
2643
+ fi ;
2644
+ for y in outn[ x] do
2645
+ if x = source or x = sink then
2646
+ mat[ x][ y + n] := true ;
2647
+ mat[ y][ x] := true ;
2648
+ elif y = source or y = sink then
2649
+ mat[ y][ x + n] := true ;
2650
+ mat[ x][ y] := true ;
2651
+ else
2652
+ mat[ y][ x + n] := true ;
2653
+ mat[ x][ y + n] := true ;
2654
+ fi ;
2655
+ od ;
2656
+ od ;
2657
+ return List(mat, x -> ListBlist([ 1 .. 2 * n] , x));
2658
+ end ;
2659
+
2660
+ # The following function is an implementation of the Edmonds-Karp algorithm
2661
+ # with some minor adjustments that take into account the fact that the
2662
+ # capacity of all edges is 1.
2663
+ edmondskarp := function (netw, source, sink )
2664
+ local flow, capacity, queue, m, predecessor, edgeindex, stop, current, n, v;
2665
+
2666
+ flow := 0 ;
2667
+ capacity := List(netw, x -> BlistList(x, x));
2668
+ # nredges := Sum(List(netw, Length));
2669
+
2670
+ while true do
2671
+ queue := [ source] ;
2672
+ m := 1 ;
2673
+ predecessor := List(netw, x -> 0 );
2674
+ edgeindex := List(netw, x -> 0 );
2675
+ stop := false ;
2676
+ while m <= Size(queue) and not stop do
2677
+ current := queue[ m] ;
2678
+ n := 0 ;
2679
+ for v in netw[ current] do
2680
+ n := n + 1 ;
2681
+ if predecessor[ v] = 0 and v <> source and capacity[ current][ n] then
2682
+ predecessor[ v] := current;
2683
+ edgeindex[ v] := n;
2684
+ Add(queue, v);
2685
+ fi ;
2686
+ if v = sink then
2687
+ stop := true ;
2688
+ break ;
2689
+ fi ;
2690
+ od ;
2691
+ m := m + 1 ;
2692
+ od ;
2693
+
2694
+ if predecessor[ sink] <> 0 then
2695
+ v := predecessor[ sink] ;
2696
+ n := edgeindex[ sink] ;
2697
+ while v <> 0 do
2698
+ capacity[ v][ n] := false ;
2699
+ n := edgeindex[ v] ;
2700
+ v := predecessor[ v] ;
2701
+ od ;
2702
+ flow := flow + 1 ;
2703
+ else
2704
+ return flow;
2705
+ fi ;
2706
+ od ;
2707
+ end ;
2708
+
2709
+ # Referring once again to Abdol-Hossein Esfahanian's paper (see newnetw, above)
2710
+ # the following lines implement Algorithm Eleven of that paper.
2711
+ mat := BooleanAdjacencyMatrix(digraph);
2712
+ degs := ListWithIdenticalEntries(DigraphNrVertices(digraph), 0 );
2713
+ for i in DigraphVertices(digraph) do
2714
+ for j in [ i + 1 .. DigraphNrVertices(digraph)] do
2715
+ if mat[ i][ j] or mat[ j][ i] then
2716
+ degs[ i] := degs[ i] + 1 ;
2717
+ degs[ j] := degs[ j] + 1 ;
2718
+ fi ;
2719
+ od ;
2720
+ od ;
2721
+
2722
+ mindegv := 0 ;
2723
+ mindeg := DigraphNrVertices(digraph) + 1 ;
2724
+ for i in DigraphVertices(digraph) do
2725
+ if degs[ i] < mindeg then
2726
+ mindeg := degs[ i] ;
2727
+ mindegv := i;
2728
+ fi ;
2729
+ od ;
2730
+
2731
+ Nv := OutNeighboursOfVertex(digraph, mindegv);
2732
+ outn := OutNeighbours(digraph);
2733
+
2734
+ for x in DigraphVertices(digraph) do
2735
+ if x <> mindegv and not mat[ x][ mindegv] and not mat[ mindegv][ x] then
2736
+ k := edmondskarp(newnetw(digraph, mindegv, x), mindegv, x);
2737
+ if k = 0 then
2738
+ return 0 ;
2739
+ else
2740
+ AddSet(kappas, k);
2741
+ fi ;
2742
+ fi ;
2743
+ od ;
2744
+
2745
+ for x in [ 1 .. Size(Nv) - 1 ] do
2746
+ for y in [ x + 1 .. Size(Nv)] do
2747
+ if not mat[ Nv[ x]][ Nv[ y]] and not mat[ Nv[ y]][ Nv[ x]] then
2748
+ k := edmondskarp(newnetw(digraph, Nv[ x] , Nv[ y] ), Nv[ x] , Nv[ y] );
2749
+ if k = 0 then
2750
+ return 0 ;
2751
+ else
2752
+ AddSet(kappas, k);
2753
+ fi ;
2754
+ fi ;
2755
+ od ;
2756
+ od ;
2757
+ return kappas[ 1 ] ;
2758
+ end );
0 commit comments