@@ -781,6 +781,200 @@ function(digraph, start, destination)
781781 return flows;
782782end );
783783
784+ # DigraphEdgeConnectivity calculated using Spanning Trees
785+ InstallMethod(DigraphEdgeConnectivity, " for a digraph" ,
786+ [ IsDigraph] ,
787+ function (digraph )
788+ local w, weights, EdgeD, VerticesED, min, u, v,
789+ sum, a, b, st, added, NeighboursV, Edges, notadded,
790+ max, NextVertex, notAddedNeighbours, non_leaf;
791+
792+ if DigraphNrVertices(digraph) = 1 then
793+ return 0 ;
794+ fi ;
795+
796+ if DigraphNrStronglyConnectedComponents(digraph) > 1 then
797+ return 0 ;
798+ fi ;
799+
800+ weights := List([ 1 .. DigraphNrVertices(digraph)] ,
801+ x -> List([ 1 .. Length(OutNeighbours(digraph)[ x] )] ,
802+ y -> 1 ));
803+ EdgeD := EdgeWeightedDigraph(digraph, weights);
804+ VerticesED := [ 1 .. DigraphNrVertices(EdgeD)] ;
805+
806+ min := - 1 ;
807+
808+ # Algorithm 4: Constructing a Spanning Tree with a large numbers of leaves
809+
810+ st := EmptyDigraph(DigraphNrVertices(EdgeD));
811+ v := 1 ;
812+ added := [ v] ;
813+
814+ while DigraphNrEdges(st) < DigraphNrVertices(EdgeD) - 1 do
815+
816+ # Add all edges incident from v
817+ NeighboursV := OutNeighbors(EdgeD)[ v] ;
818+
819+ Edges := List([ 1 .. Length(NeighboursV)] ,
820+ x -> [ v, OutNeighbours(EdgeD)[ v][ x]] );
821+
822+ Edges := Difference(Edges, [[ v, v]] );
823+
824+ st := DigraphAddEdges(st, Edges);
825+ Append(added, Difference(OutNeighbours(EdgeD)[ v] , added));
826+
827+ # Select the neighbour to v with the highest number of not-added neighbours:
828+
829+ notadded := Difference(VerticesED, added);
830+ max := 0 ;
831+ NextVertex := v;
832+
833+ # Preventing infinite iteration if the current vertex has no neighbours
834+ if (Length(NeighboursV) = 0 ) then
835+ # Pick from a vertex that hasn't been added yet
836+ NextVertex := notadded[ 1 ] ;
837+ fi ;
838+
839+ for w in Difference(NeighboursV, [ v] ) do ;
840+ notAddedNeighbours := Intersection(notadded, OutNeighbours(EdgeD)[ w] );
841+ if (Length(notAddedNeighbours) > max) then
842+ max := Length(notAddedNeighbours);
843+ NextVertex := w;
844+ fi ;
845+ od ;
846+
847+ v := NextVertex;
848+
849+ od ;
850+
851+ # Algorithm 5: Using Algorithm 4 to find the Edge Connectivity
852+
853+ non_leaf := [] ;
854+ for b in VerticesED do
855+ if not IsEmpty(OutNeighbours(st)[ b] ) then
856+ Append(non_leaf, [ b] );
857+ fi ;
858+ od ;
859+
860+ # Get the smaller of non_leaf and Difference(Vertices in EdgeD, non_leaf)
861+
862+ if (Length(non_leaf) > 1 ) then
863+ u := non_leaf[ 1 ] ;
864+
865+ for v in [ 2 .. Length(non_leaf)] do
866+ a := DigraphMaximumFlow(EdgeD, u, non_leaf[ v] )[ u] ;
867+ b := DigraphMaximumFlow(EdgeD, non_leaf[ v] , u)[ non_leaf[ v]] ;
868+
869+ sum := Minimum(Sum(a), Sum(b));
870+ if (sum < min or min = - 1 ) then
871+ min := sum;
872+ fi ;
873+
874+ if (sum = 0 ) then
875+ return 0 ;
876+ fi ;
877+ od ;
878+
879+ min := Minimum(min, Minimum(Minimum(OutDegrees(EdgeD)),
880+ Minimum(InDegrees(EdgeD))));
881+ else
882+ # In the case of spanning trees with only one non-leaf node,
883+ # the above algorithm does not work
884+
885+ u := 1 ;
886+ for v in [ 2 .. DigraphNrVertices(EdgeD)] do
887+ a := DigraphMaximumFlow(EdgeD, u, v)[ u] ;
888+ b := DigraphMaximumFlow(EdgeD, v, u)[ v] ;
889+
890+ sum := Minimum(Sum(a), Sum(b));
891+ if (sum < min or min = - 1 ) then
892+ min := sum;
893+ fi ;
894+
895+ if (sum = 0 ) then
896+ return 0 ;
897+ fi ;
898+
899+ od ;
900+ fi ;
901+
902+ if (min = - 1 ) then
903+ return 0 ;
904+ fi ;
905+
906+ return min;
907+ end );
908+
909+ # Digraph EdgeConnectivity calculated with Dominating Sets
910+ InstallMethod(DigraphEdgeConnectivityDS, " for a digraph" ,
911+ [ IsDigraph] ,
912+ function (digraph )
913+ # Form an identical but edge weighted digraph with all edge weights as 1:
914+ local weights, i, u, v, w, neighbourhood, EdgeD,
915+ maxFlow, min, sum, a, b, V, added, st, non_leaf, max,
916+ notAddedNeighbours, notadded, NextVertex, NeighboursV,
917+ neighbour, Edges, D, VerticesLeft, VerticesED;
918+
919+ if DigraphNrVertices(digraph) = 1 then
920+ return 0 ;
921+ fi ;
922+
923+ if DigraphNrStronglyConnectedComponents(digraph) > 1 then
924+ return 0 ;
925+ fi ;
926+
927+ weights := List([ 1 .. DigraphNrVertices(digraph)] ,
928+ x -> List([ 1 .. Length(OutNeighbours(digraph)[ x] )] ,
929+ y -> 1 ));
930+ EdgeD := EdgeWeightedDigraph(digraph, weights);
931+
932+ min := - 1 ;
933+
934+ # Algorithm 7: Creating a dominating set of the digraph
935+
936+ D := DigraphDominatingSet(digraph);
937+
938+ # Algorithm 6:
939+
940+ if Length(D) > 1 then
941+
942+ v := D[ 1 ] ;
943+ for i in [ 2 .. Length(D)] do
944+ w := D[ i] ;
945+ a := DigraphMaximumFlow(EdgeD, v, w)[ v] ;
946+ b := DigraphMaximumFlow(EdgeD, w, v)[ w] ;
947+
948+ sum := Minimum(Sum(a), Sum(b));
949+ if (sum < min or min = - 1 ) then
950+ min := sum;
951+ fi ;
952+ od ;
953+
954+ else
955+ # If the dominating set of EdgeD is of Length 1,
956+ # the above algorithm will not work
957+
958+ u := 1 ;
959+
960+ for v in [ 2 .. DigraphNrVertices(EdgeD)] do
961+ a := DigraphMaximumFlow(EdgeD, u, v)[ u] ;
962+ b := DigraphMaximumFlow(EdgeD, v, u)[ v] ;
963+
964+ sum := Minimum(Sum(a), Sum(b));
965+ if (sum < min or min = - 1 ) then
966+ min := sum;
967+ fi ;
968+
969+ od ;
970+ fi ;
971+
972+ return Minimum(min,
973+ Minimum(Minimum(OutDegrees(EdgeD)),
974+ Minimum(InDegrees(EdgeD))));
975+
976+ end );
977+
784978# ############################################################################
785979# 6. Random edge weighted digraphs
786980# ############################################################################
0 commit comments