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