-
Notifications
You must be signed in to change notification settings - Fork 86
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
Implement isdigraphical
and fix isgraphical
#186
Conversation
Codecov Report
@@ Coverage Diff @@
## master #186 +/- ##
==========================================
+ Coverage 97.40% 97.43% +0.03%
==========================================
Files 109 113 +4
Lines 6470 6554 +84
==========================================
+ Hits 6302 6386 +84
Misses 168 168 |
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.
Thank you for the contribution!
Done @aurorarossi, Thanks for your suggestions. |
This branch has conflicts because we recently introduced a Julia Formatter. Can you do a merge with Graphs.jl/master? And format the files you changed? I tried to fix it but I don't have permissions to push to your branch. Thanks! |
src/connectivity.jl
Outdated
|
||
n = length(indegree_sequence) | ||
|
||
n == length(outdegree_sequence) || return false |
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.
Wouldn't it be more appropriate to throw an exception in this case?
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.
Yes, done.
src/connectivity.jl
Outdated
``` | ||
for each integer r <= n-1 | ||
""" | ||
function isdigraphical(indegree_sequence::Vector{<:Integer}, outdegree_sequence::Vector{<:Integer} ) |
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.
function isdigraphical(indegree_sequence::Vector{<:Integer}, outdegree_sequence::Vector{<:Integer} ) | |
function isdigraphical(indegree_sequence::AbstractVector{<:Integer}, outdegree_sequence::AbstractVector{<:Integer} ) |
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.
Done, but that is in contradiction with the @aurorarossi's request.
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.
Which one?
I suggested changing the signature style of the function in the docstring, but not here
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.
Ops sorry @aurorarossi, we've just noticed that Graphs.jl uses two different conventions for the code and its docstring.
We're going to keep the signature according to @simonschoelly's suggestion then.
src/connectivity.jl
Outdated
@inbounds for r = 1:(n - 1) | ||
|
||
indegree_sum += sorted_indegree_sequence[r] | ||
outdegree_min_sum = sum([min(sorted_outdegree_sequence[i], r-1) for i in 1:r]) |
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.
Here we allocate a new Vector in each iteration of the loop. Can we do this differently?
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.
We were not able to use the same strategy adopted in isgraphical
. For further details see in the comments.
sdg = SimpleDiGraph(10, 90) | ||
@test @inferred(isdigraphical(indegree(sdg), outdegree(sdg))) | ||
@test !@inferred(isdigraphical([1,1,1], [1,1,0])) | ||
|
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.
Can we also have a few edge cases here? Such as
- Empty vectors
- Graphs that only have a realization if there is a self-loop.
- Graphs where the sum of the in and out degree sequences if the same, but there is still no valid realization.
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.
We've just noticed that isgraphical
and isdigraphical
don't work properly in the edge cases you mentioned.
For example:
-
isgraphical([2])
returnstrue
even if it's not possible to realise a simple undirected graph (no self-loops, no multi-edges) with just a vertex with$d(v)=2$ . -
isdigraphical([1],[1])
returnstrue
even if it's not possible to realise a simple directed graph (no self-loops, no multi-edges) with just a vertex with$d_{in}(v)=d_{out}(v)=1$ .
@aurorarossi, we have just formatted the relevant files. |
isdigraphical
isdigraphical
and correct isgraphical
@InterdisciplinaryPhysicsTeam Now there is a lot of noise in this PR because of the formatting changes. Perhaps if you rebase on the latest master branch, they will go away? |
Co-Authored-By: Claudio Moroni <43729990+ClaudMor@users.noreply.github.com> Co-Authored-By: Pietro Monticone <38562595+pitmonticone@users.noreply.github.com>
Co-Authored-By: Claudio Moroni <43729990+ClaudMor@users.noreply.github.com> Co-Authored-By: Pietro Monticone <38562595+pitmonticone@users.noreply.github.com>
Co-Authored-By: Claudio Moroni <43729990+ClaudMor@users.noreply.github.com> Co-Authored-By: Pietro Monticone <38562595+pitmonticone@users.noreply.github.com>
Hello @simonschoelly, We rebased as you asked and updated the |
Co-Authored-By: Claudio Moroni <43729990+ClaudMor@users.noreply.github.com> Co-Authored-By: Pietro Monticone <38562595+pitmonticone@users.noreply.github.com>
isdigraphical
and correct isgraphical
isdigraphical
and fix isgraphical
Hello @simonschoelly @aurorarossi @gdalle, Since we are not maintainers, we need our fork to be on par with Graphs.jl's master branch in order to open new pull requests. Anyway, we cannot do it until this is merged. May anyone with write permission review and merge this? |
src/connectivity.jl
Outdated
According to Fulkerson-Chen-Anstee theorem, a sequence ``\\{(a_1, b_1), ...,(a_n, b_n)\\}`` (sorted in descending order of a) is graphic iff the sum of vertex degrees is even and ``\\sum_{i = 1}^{n} a_i = \\sum_{i = 1}^{n} b_i\\}`` and the sequence obeys the property - | ||
```math | ||
\\sum_{i=1}^{r} a_i \\leq \\sum_{i=r+1}^n min(r-1,b_i) + \\sum_{i=r+1}^n min(r,b_i) | ||
``` | ||
for each integer r <= n-1. |
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.
Do you have a source for these conditions? Because the ones on Wikipedia look differently.
I also notices that this algorithm does return incorrect results in some cases:
# would only work with a self-loop, but we don't allow these, right?
julia> isdigraphical([1],[1])
true
# would require multi-edges
julia> isdigraphical([5],[5])
true
# but this should also be true if we allow self-loops.
julia> isdigraphical([1,0],[1,0])
false
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.
Also, I was wondering if latex heavy docstrings are a good idea? We don't need to change it in this PR, as we always can do it latter, the issue is just that in the REPL it looks like this:
help?> isdigraphical
search: isdigraphical
isdigraphical(indegree_sequence, outdegree_sequence)
Check whether the given indegree sequence and outdegree sequence are digraphical, that is whether
they can be the indegree and outdegree sequence of a digraph.
Implementation Notes
––––––––––––––––––––––
According to Fulkerson-Chen-Anstee theorem, a sequence \{(a_1, b_1), ...,(a_n, b_n)\} (sorted in
descending order of a) is graphic iff the sum of vertex degrees is even and \sum_{i = 1}^{n} a_i =
\sum_{i = 1}^{n} b_i\} and the sequence obeys the property -
\sum_{i=1}^{r} a_i \leq \sum_{i=r+1}^n min(r-1,b_i) + \sum_{i=r+1}^n min(r,b_i)
for each integer r <= n-1.
See also: isgraphical
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.
We removed the "the sum of vertex degrees is even" part from the docstring of isdigraphical
which could be misleading.
The three cases you mentioned should now be fixed and added to tests. Thanks for pointing them out.
We will happily comply with whatever suggestion you give us for formatting docstrings.
src/connectivity.jl
Outdated
all(degs .>= 0) || | ||
throw(ArgumentError("The degree sequence must contain non-negative integers only.")) |
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.
Wouldn't it be more reasonable to just return false
here? Of course if that is so, we should probably do the same thing for isdigraphical
.
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.
We thought that false
was reserved for when "the degree sequence is valid but not graphical", while errors should be thrown if the degree sequence is not even valid.
If it isn't appropriate we will change the behavior.
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.
I leave the decision up too you. One thing that is nice about not throwing an error, that a user does not have to make an extra check for an error, if their input might contain a negative number.
But then we probably should also check, that all degrees are less or equal than n - 1
?
Where is would still leave the throws check in, is in the isdigraphical
method for inputs of different lengths.
Also note that by throwing an exception in isgraphical
we kind of introduce a breaking change - but as this is a very rare edge case, I think that should be ok.
Let me know what you decide.
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.
Thanks for your argumentation.
We agree that returning false
allows for simpler usage, and if the user wishes to get an error in specific circumstances, she/he may wrap the function. Thus we now return false
when negative degrees are present, or when a degree exceeds n-1
.
isdigraphical(indegree_sequence, outdegree_sequence) | ||
|
||
Check whether the given indegree sequence and outdegree sequence are digraphical, that is whether they can be the indegree and outdegree sequence of a digraph. | ||
|
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.
We should probably mention here that
- The digraph cannot have self-loops
indegree_sequence
andoutdegree_sequence
are not independent, i.e. if entryi
ofindegree_sequence
has valuea_i
and entryi
ofoutdegree_sequence
has valueb_i
then there will be a vertex with indegreea_i
and outdegreeb_i
in the realization. (maybe there is an easier way to express this).
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.
We modified the docstring trying to include your suggestions. Thanks.
src/connectivity.jl
Outdated
) | ||
|
||
n = length(indegree_sequence) | ||
n == length(outdegree_sequence) || return false |
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.
We already check this on line 783.
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.
We removed the redundant check and moved the definition of the variable n
to the top of the function.
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.
Hello @simonschoelly @aurorarossi @gdalle,
Since we are not maintainers, we need our fork to be on par with Graphs.jl's master branch in order to open new pull requests. Anyway, we cannot do it until this is merged.
May anyone with write permission review and merge this?
I am not sure, what you mean, by not being able to open new pull requests?
In any case, I think there are still some bugs here, that need to be fixed before we can merge.
Co-Authored-By: Pietro Monticone <38562595+pitmonticone@users.noreply.github.com> Co-Authored-By: Claudio Moroni <43729990+ClaudMor@users.noreply.github.com>
Hi @simonschoelly , We realized that "not being able to open new pull requests" was due to a mistake of ours, we apologize for that. We hope that the fixes above comply with your comments. |
Some small fixes for the formula in the docstring and some decision to make, if we should throw errors - and then I think we can finally merge this. |
Co-authored-by: Simon Schölly <sischoel@gmail.com>
Co-authored-by: Simon Schölly <sischoel@gmail.com>
Co-Authored-By: Pietro Monticone <38562595+pitmonticone@users.noreply.github.com> Co-Authored-By: Claudio Moroni <43729990+ClaudMor@users.noreply.github.com>
We committed your suggestions and accepted your proposal to return |
Merged, thanks! |
Hello,
We're the developers of MultilayerGraphs.jl.
In this PR we implement the test for graphicality in the directed without loops case (see Fulkerson–Chen–Anstee theorem).
The new function is called
isdigraphical
, and we tried to implement it as similarly as we could to the already existingisgraphical
. Implementation differences are highlighted using comments in the code.We have already written the docstrings and added tests.
CC: @pitmonticone @ClaudMor