-
Notifications
You must be signed in to change notification settings - Fork 67
Implementing DigraphEdgeConnectivity #884
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
90a9a89
3027792
300ebc5
72e68c4
e697fa4
15a5150
05f99d5
57c908e
60505dc
e1bbe0c
4205ed0
531fc71
75ac98a
c3645ab
bcf23b8
dfec296
37a044e
acc9c0d
35128b6
a167c36
94f52e1
47be251
06e5fdf
38b4803
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -2702,6 +2702,47 @@ gap> Length(M); | |||||
| </ManSection> | ||||||
| <#/GAPDoc> | ||||||
|
|
||||||
| <#GAPDoc Label="AttrDigraphGreedyOutDominatingSet"> | ||||||
| <ManSection> | ||||||
| <Attr Name="DigraphGreedyOutDominatingSet" Arg="digraph"/> | ||||||
| <Attr Name="DigraphGreedyInDominatingSet" Arg="digraph"/> | ||||||
| <Returns>A list of positive integers</Returns> | ||||||
| <Description> | ||||||
| <C>DigraphGreedyOutDominatingSet</C> returns the unique <E>greedy | ||||||
| out-dominating set</E> of <A>digraph</A> with respect to the ordering | ||||||
| <M>1 < 2 < ... < n</M> where <M>n</M> is the number of vertices in | ||||||
| <A>digraph</A>. An <E>out-dominating set</E> is a subset <M>S</M> of | ||||||
| vertices of <A>digraph</A> such that every vertex of <A>digraph</A> is | ||||||
| either in <M>S</M> or an out-neighbour of a vertex in <M>S</M>. Such a | ||||||
| set is <E>greedy</E>, if it is obtained by starting with an empty set | ||||||
| <M>S</M> and repeatedly adding to <M>S</M> the least vertex that is not | ||||||
| in <M>S</M> and not and out-neighbour of <M>S</M>. | ||||||
|
|
||||||
| See also <Ref Oper="IsDigraphOutDominatingSet"/> for a further | ||||||
| information on dominating sets, and <Ref | ||||||
| Oper="DigraphGreedyOutDominatingSet"/> for a version of this function | ||||||
| that finds a greedy out-dominating set with respect to an arbitrary | ||||||
| ordering on vertices. | ||||||
|
|
||||||
| Similarly, <C>DigraphGreedyInDominatingSet</C> returns the unique <E>greedy | ||||||
| in-dominating set</E> of <A>digraph</A> with respect to the ordering | ||||||
| <M>1 < 2 < ... < n</M> where <M>n</M> is the number of vertices in | ||||||
| <A>digraph</A>. This is equivalently the greedy out-dominating set of | ||||||
| the <Ref Attr="DigraphDual"/> of <A>digraph</A>. | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
The dual is the graph where every non-edge becomes an edge and vice versa, do you mean the reverse? |
||||||
|
|
||||||
| See also <Ref Oper="IsDigraphInDominatingSet"/> and <Ref | ||||||
| Oper="DigraphGreedyInDominatingSet"/>. | ||||||
| <Example><![CDATA[ | ||||||
| gap> D := Digraph([[2, 4], [3], [1, 5], [3], [4]]);; | ||||||
| gap> A := DigraphGreedyOutDominatingSet(D); | ||||||
| [ 1, 3 ] | ||||||
| gap> A := DigraphGreedyInDominatingSet(D); | ||||||
| [ 1, 2, 4 ] | ||||||
| ]]></Example> | ||||||
| </Description> | ||||||
| </ManSection> | ||||||
| <#/GAPDoc> | ||||||
|
|
||||||
| <#GAPDoc Label="DigraphVertexConnectivity"> | ||||||
| <ManSection> | ||||||
| <Attr Name="DigraphVertexConnectivity" Arg="digraph"/> | ||||||
|
|
@@ -2777,6 +2818,40 @@ gap> DigraphVertexConnectivity(CompleteDigraph(5)); | |||||
| </ManSection> | ||||||
| <#/GAPDoc> | ||||||
|
|
||||||
| <#GAPDoc Label="DigraphEdgeConnectivity"> | ||||||
| <ManSection> | ||||||
| <Attr Name="DigraphEdgeConnectivity" Arg="digraph"/> | ||||||
| <Returns>An integer</Returns> | ||||||
| <Description> | ||||||
| This function returns the edge connectivity of a symmetric digraph | ||||||
| <A>digraph</A>.<P/> | ||||||
|
|
||||||
| The edge connectivity of a symmetric digraph is the size <M>k</M> of the | ||||||
| smallest set of edges whose removal would make the digraph disconnected | ||||||
| (in the sense of <Ref Prop="IsConnectedDigraph"/>).<P/> | ||||||
|
|
||||||
| The implementation makes use of the | ||||||
| <C>DigraphMaximumFlow(<A>digraph</A>)</C> function, assuming each edge has | ||||||
| weight 1, then using the max-flow min-cut theorem to determine the size of | ||||||
| the minimum cut. See also <Ref Attr="DigraphMaximumFlow"/>.<P/> | ||||||
|
|
||||||
| The edge connectivity of any symmetric bridgeless digraph is at least 2. | ||||||
| See also <Ref Prop="IsBridgelessDigraph"/>. | ||||||
| <Example><![CDATA[ | ||||||
| gap> d := Digraph([[4], [4], [4], [1, 2, 3]]);; | ||||||
| gap> DigraphEdgeConnectivity(d); | ||||||
| 1 | ||||||
| gap> D := RandomDigraph(1);; | ||||||
| gap> DigraphEdgeConnectivity(D); | ||||||
| 0 | ||||||
| gap> d := Digraph([[2, 3], [1, 4], [1, 4], [2, 3]]);; | ||||||
| gap> DigraphEdgeConnectivity(d); | ||||||
| 2 | ||||||
| ]]></Example> | ||||||
| </Description> | ||||||
| </ManSection> | ||||||
| <#/GAPDoc> | ||||||
|
|
||||||
| <#GAPDoc Label="NonUpperSemimodularPair"> | ||||||
| <ManSection> | ||||||
| <Attr Name="NonUpperSemimodularPair" Arg="D"/> | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -1954,6 +1954,92 @@ rec( idom := [ 2, fail, 2, 2, 2 ], preorder := [ 2, 1, 3, 4, 5 ] ) | |||||
| </ManSection> | ||||||
| <#/GAPDoc> | ||||||
|
|
||||||
| <#GAPDoc Label="IsDigraphOutDominatingSet"> | ||||||
| <ManSection> | ||||||
| <Oper Name="IsDigraphOutDominatingSet" Arg="digraph, list"/> | ||||||
| <Oper Name="IsDigraphInDominatingSet" Arg="digraph, list"/> | ||||||
| <Returns><K>true</K> or <K>false</K>.</Returns> | ||||||
| <Description> | ||||||
| If <A>digraph</A> is a digraph and <A>list</A> is a strictly sorted list of | ||||||
| vertices of <A>digraph</A>, then <C>IsDigraphOutDominatingSet</C> | ||||||
| returns <K>true</K> if <A>list</A> is an out-dominating set of <A>digraph</A>. | ||||||
| Similarly, the operation <C>IsDigraphInDominatingSet</C> returns <K>true</K> | ||||||
| if <A>list</A> is an in-dominating set of <A>digraph</A>. | ||||||
| Otherwise, each of these operations return <K>false</K>. | ||||||
| <P/> | ||||||
|
|
||||||
| An <E>out-dominating set</E> of <A>digraph</A> is a subset <M>S</M> of | ||||||
| vertices of <A>digraph</A> such that every vertex of <A>digraph</A> is | ||||||
| either in <M>S</M> or an out-neighbour of a vertex in <M>S</M>. | ||||||
| An <E>in-dominating set</E> of <A>digraph</A> is a subset <M>S</M> of | ||||||
| vertices of <A>digraph</A> such that every vertex of <A>digraph</A> is | ||||||
| either in <M>S</M> or an in-neighbour of a vertex in <M>S</M>. | ||||||
|
|
||||||
| <Example><![CDATA[ | ||||||
| gap> D := Digraph([[2, 4], [3], [1, 5], [3], [4]]);; | ||||||
| gap> IsDigraphOutDominatingSet(D, [1, 3]); | ||||||
| true | ||||||
| gap> IsDigraphOutDominatingSet(D, [1, 3, 5]); | ||||||
| true | ||||||
| gap> IsDigraphOutDominatingSet(D, [3, 5]); | ||||||
| false | ||||||
| gap> IsDigraphOutDominatingSet(D, [3, 1, 5, 2, 4]); | ||||||
| false | ||||||
| gap> IsDigraphInDominatingSet(D, [3, 4]); | ||||||
| true | ||||||
| gap> IsDigraphInDominatingSet(D, [1, 3, 5]); | ||||||
| true | ||||||
| gap> IsDigraphInDominatingSet(D, [3, 5]); | ||||||
| false | ||||||
| gap> IsDigraphInDominatingSet(D, [3, 1, 5, 2, 4]); | ||||||
| false | ||||||
| ]]></Example> | ||||||
| </Description> | ||||||
| </ManSection> | ||||||
| <#/GAPDoc> | ||||||
|
|
||||||
| <#GAPDoc Label="OperDigraphGreedyOutDominatingSet"> | ||||||
| <ManSection> | ||||||
| <Oper Name="DigraphGreedyOutDominatingSet" Arg="digraph, order"/> | ||||||
| <Oper Name="DigraphGreedyInDominatingSet" Arg="digraph, order"/> | ||||||
| <Returns>A list of positive integers</Returns> | ||||||
| <Description> | ||||||
| <C>DigraphGreedyOutDominatingSet</C> returns the unique <E>greedy | ||||||
| out-dominating set</E> of <A>digraph</A> with respect to the ordering | ||||||
| that the list <A>order</A> induced on the vertices in | ||||||
| <A>digraph</A>. An <E>out-dominating set</E> is a subset <M>S</M> of | ||||||
| vertices of <A>digraph</A> such that every vertex of <A>digraph</A> is | ||||||
| either in <M>S</M> or an out-neighbour of a vertex in <M>S</M>. Such a | ||||||
| set is <E>greedy</E>, if it is obtained by starting with an empty set | ||||||
| <M>S</M> and repeatedly adding to <M>S</M> the least (with respect to the | ||||||
| ordering <A>order</A>) vertex that is not in <M>S</M> and not and | ||||||
| out-neighbour of <M>S</M>. | ||||||
|
|
||||||
| See also <Ref Oper="IsDigraphOutDominatingSet"/> for a further | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| information on dominating sets, and <Ref | ||||||
| Attr="DigraphGreedyOutDominatingSet"/> for the attribute version of this | ||||||
| function that finds a greedy out-dominating set with respect to the | ||||||
| ordering <M>1 < 2 < ... < n </M> on the vertices of <A>digraph</A>. | ||||||
|
|
||||||
| Similarly, <C>DigraphGreedyInDominatingSet</C> returns the unique <E>greedy | ||||||
| in-dominating set</E> of <A>digraph</A> with respect to the ordering | ||||||
| that the list <A>order</A> induces on the vertices in | ||||||
| <A>digraph</A>. This is equivalently the greedy out-dominating set of | ||||||
| the <Ref Attr="DigraphDual"/> of <A>digraph</A>. | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Same comment as above. |
||||||
|
|
||||||
| See also <Ref Oper="IsDigraphInDominatingSet"/> and <Ref | ||||||
| Attr="DigraphGreedyInDominatingSet"/>. | ||||||
| <Example><![CDATA[ | ||||||
| gap> D := Digraph([[2, 4], [3], [1, 5], [3], [4]]);; | ||||||
| gap> DigraphGreedyOutDominatingSet(D, [2, 1, 3, 4, 5]); | ||||||
| [ 1, 2, 5 ] | ||||||
| gap> DigraphGreedyInDominatingSet(D, [5, 1, 3, 4, 2]); | ||||||
| [ 1, 2, 4, 5 ] | ||||||
| ]]></Example> | ||||||
| </Description> | ||||||
| </ManSection> | ||||||
| <#/GAPDoc> | ||||||
|
|
||||||
| <#GAPDoc Label="PartialOrderDigraphMeetOfVertices"> | ||||||
| <ManSection> | ||||||
| <Oper Name="PartialOrderDigraphMeetOfVertices" | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -330,6 +330,7 @@ gap> DigraphMinimumCutSet(g, 1, 3); | |||
| </ManSection> | ||||
| <#/GAPDoc> | ||||
|
|
||||
|
|
||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
No change required in this file. |
||||
| <#GAPDoc Label="RandomUniqueEdgeWeightedDigraph"> | ||||
| <ManSection> | ||||
| <Oper Name="RandomUniqueEdgeWeightedDigraph" Arg="[filt, ]n[, p]"/> | ||||
|
|
||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3504,6 +3504,149 @@ function(D) | |
| return kappa_min; | ||
| end); | ||
|
|
||
| ############################################################################# | ||
| # Digraph Edge Connectivity | ||
| ############################################################################# | ||
|
|
||
| # Algorithms constructed off the algorithms detailed in: | ||
| # https://www.cse.msu.edu/~cse835/Papers/Graph_connectivity_revised.pdf | ||
| # Each Algorithm uses a different method to decrease the time complexity, | ||
| # of calculating Edge Connectivity, though all make use of DigraphMaximumFlow() | ||
| # due to the Max-Flow, Min-Cut Theorem | ||
|
|
||
| # Algorithm 1: Calculating the Maximum Flow of every possible source and sink | ||
| # Algorithm 2: Calculating the Maximum Flow to all sinks of an arbitrary source | ||
| # Algorithm 3: Finding Maximum Flow within the non-leaves of a Spanning Tree | ||
| # Algorithm 4: Constructing a spanning tree with a high number of leaves | ||
| # Algorithm 5: Using the spanning tree^ to find Maximum Flow within non-leaves | ||
| # Algorithm 6: Finding Maximum Flow within a dominating set of the digraph | ||
| # Algorithm 7: Constructing a dominating set for use in Algorithm 6 | ||
|
|
||
| # This function computes the greedy dominating set for the subdigraph | ||
| # of a digraph induced by a set of vertices. The neighbour_fun function | ||
| # determines if in or out-edges are used. Pass OutNeighboursOfVertex | ||
| # for out-edges and InNeighboursOfVertex for in-edges. | ||
| # | ||
| # In other words, we find a subset S of the vertices in the parameter | ||
| # vertices such that every vertex in vertices is in S or adjacent | ||
| # to a vertex in S. | ||
| # | ||
| # This is done in a greedy manner by including every vertex in | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is probably not important, but can you possibly reflow this comment, the line breaks look weird to me. |
||
| # vertices in order, if it is not already adjacent to some | ||
| # vertex in the current dominating set. The vertices are | ||
| # processed in the same order as they occur in the | ||
| # parameter vertices. | ||
| # | ||
| # Implements Algorithm 7 in : | ||
| # https://www.cse.msu.edu/~cse835/Papers/Graph_connectivity_revised.pdf | ||
| BindGlobal("DIGRAPHS_GreedyDominatingSet", | ||
| function(digraph, vertices, neighbour_fun) | ||
| local S, seen, neighbour, vertex; | ||
|
|
||
| Assert(1, | ||
| neighbour_fun = OutNeighboursOfVertex or | ||
| neighbour_fun = InNeighboursOfVertex); | ||
|
|
||
| seen := BlistList(DigraphVertices(digraph), []); | ||
| S := []; | ||
| for vertex in vertices do | ||
| if not seen[vertex] then | ||
| seen[vertex] := true; | ||
| Add(S, vertex); | ||
| for neighbour in neighbour_fun(digraph, vertex) do | ||
| seen[neighbour] := true; | ||
| od; | ||
| fi; | ||
| od; | ||
|
|
||
| return S; | ||
| end); | ||
|
|
||
| InstallMethod(DigraphGreedyOutDominatingSet, "for a digraph", [IsDigraph], | ||
| digraph -> | ||
| DIGRAPHS_GreedyDominatingSet( | ||
| digraph, | ||
| DigraphVertices(digraph), | ||
| OutNeighboursOfVertex)); | ||
|
|
||
| InstallMethod(DigraphGreedyInDominatingSet, "for a digraph", [IsDigraph], | ||
| digraph -> | ||
| DIGRAPHS_GreedyDominatingSet( | ||
| digraph, | ||
| DigraphVertices(digraph), | ||
| InNeighboursOfVertex)); | ||
| # Algorithms 4-7 are used below: | ||
|
|
||
| # Digraph EdgeConnectivity calculated with Dominating Sets (Algorithm 6-7) | ||
| InstallMethod(DigraphEdgeConnectivity, "for a symmetric digraph", | ||
| [IsDigraph], | ||
| function(digraph) | ||
| # Form an identical but edge weighted digraph with all edge weights as 1: | ||
| local weights, i, u, v, w, neighbourhood, EdgeD, | ||
| maxFlow, min, sum, a, b, V, added, st, non_leaf, max, | ||
| notAddedNeighbours, notadded, NextVertex, NeighboursV, | ||
| neighbour, Edges, D, VerticesLeft, VerticesED; | ||
|
|
||
| # check for symmetric digraph | ||
| if not IsSymmetricDigraph(digraph) then | ||
| ErrorNoReturn("the argument <digraph> must be a symmetric digraph,"); | ||
| fi; | ||
|
|
||
| if DigraphNrVertices(digraph) = 1 or | ||
| DigraphNrConnectedComponents(digraph) > 1 then | ||
| return 0; | ||
| fi; | ||
|
|
||
| EdgeD := UnitEdgeWeightedDigraph(DigraphImmutableCopyIfMutable(digraph)); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Move this line down to just before |
||
|
|
||
| min := -1; | ||
|
|
||
| # Algorithm 7: Creating a dominating set of the digraph | ||
| D := DIGRAPHS_GreedyDominatingSet( | ||
| digraph, | ||
| Shuffle([1 .. DigraphNrVertices(digraph)]), | ||
| OutNeighboursOfVertex); | ||
|
|
||
| # Algorithm 6: Using the dominating set created to determine the Maximum Flow | ||
|
|
||
| if Length(D) > 1 then | ||
|
|
||
| v := D[1]; | ||
| for i in [2 .. Length(D)] do | ||
| w := D[i]; | ||
| a := DigraphMaximumFlow(EdgeD, v, w)[v]; | ||
| b := DigraphMaximumFlow(EdgeD, w, v)[w]; | ||
|
|
||
| sum := Minimum(Sum(a), Sum(b)); | ||
| if (sum < min or min = -1) then | ||
| min := sum; | ||
| fi; | ||
| od; | ||
|
|
||
| else | ||
| # If the dominating set of EdgeD is of Length 1, | ||
| # the above algorithm will not work | ||
| # Revert to iterating through all vertices of the original digraph | ||
|
|
||
| u := 1; | ||
|
|
||
| for v in [2 .. DigraphNrVertices(EdgeD)] do | ||
| a := DigraphMaximumFlow(EdgeD, u, v)[u]; | ||
| b := DigraphMaximumFlow(EdgeD, v, u)[v]; | ||
|
|
||
| sum := Minimum(Sum(a), Sum(b)); | ||
| if (sum < min or min = -1) then | ||
| min := sum; | ||
| fi; | ||
|
|
||
| od; | ||
| fi; | ||
|
|
||
| return Minimum(min, | ||
| Minimum(Minimum(OutDegrees(EdgeD)), | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| Minimum(InDegrees(EdgeD)))); | ||
| end); | ||
|
|
||
| # The following function is a transliteration from python to GAP of | ||
| # the function find_nonsemimodular_pair | ||
| # in sage/src/sage/combinat/posets/hasse_diagram.py | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.