From c378d9fa53484c579fda22287831ff1664b9849d Mon Sep 17 00:00:00 2001 From: Yiran Zhu Date: Fri, 10 Jan 2025 23:59:33 +0000 Subject: [PATCH 1/4] Fix error in implementation of Erdos-Gallai condition in isgraphical MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #400 Fix `isgraphical` function to correctly handle non-graphical sequences. # Error in current implementation `mindeg` is computed globally at the start using `min(i, sorted_degs[i])` for all indices. However, the Erdös-Gallai condition requires dynamically calculating `min(r, sorted_degs[i])` for vertices after the current index `r`. # What changed * Update the Erdös-Gallai condition check to calculate the sum of the minimum of r and the degrees of the vertices. * Add a test case in `test/connectivity.jl` to verify that `isgraphical` returns false for the sequence [4,2,2,2,0]. --- For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/JuliaGraphs/Graphs.jl/issues/400?shareId=XXXX-XXXX-XXXX-XXXX). --- src/connectivity.jl | 11 +++-------- test/connectivity.jl | 1 + 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/connectivity.jl b/src/connectivity.jl index 18e0aca94..693547df7 100644 --- a/src/connectivity.jl +++ b/src/connectivity.jl @@ -805,17 +805,12 @@ function isgraphical(degs::AbstractVector{<:Integer}) sorted_degs = sort(degs; rev=true) # Compute the length of the degree sequence cur_sum = zero(UInt64) - # Compute the minimum of each degree and the corresponding index - mindeg = Vector{UInt64}(undef, n) - @inbounds for i in 1:n - mindeg[i] = min(i, sorted_degs[i]) - end # Check if the degree sequence satisfies the Erdös-Gallai condition - cum_min = sum(mindeg) @inbounds for r in 1:(n - 1) cur_sum += sorted_degs[r] - cum_min -= mindeg[r] - cond = cur_sum <= (r * (r - 1) + cum_min) + # Calculate the sum of the minimum of r and the degrees of the vertices + mid_deg_sum = sum([min(r, sorted_degs[i]) for i in (r + 1):n]) + cond = cur_sum <= (r * (r - 1) + mid_deg_sum) cond || return false end return true diff --git a/test/connectivity.jl b/test/connectivity.jl index ae5a8ccc6..bdb0cf521 100644 --- a/test/connectivity.jl +++ b/test/connectivity.jl @@ -316,6 +316,7 @@ @test @inferred(isgraphical([2, 2, 2])) @test @inferred(isgraphical(fill(3, 10))) @test @inferred(isgraphical(Integer[])) + @test @inferred(!isgraphical([4, 2, 2, 2, 0])) ##@test !@inferred(isgraphical([2])) # Test simple digraphicality From c5aca53106e449247847cbfd4e38fe41c17479ce Mon Sep 17 00:00:00 2001 From: Syuizen Date: Tue, 21 Jan 2025 21:04:36 +0000 Subject: [PATCH 2/4] improve isgraphical from O(n^2) to O(n*log(n)) --- src/connectivity.jl | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/src/connectivity.jl b/src/connectivity.jl index 693547df7..a258e7fe7 100644 --- a/src/connectivity.jl +++ b/src/connectivity.jl @@ -798,19 +798,49 @@ function isgraphical(degs::AbstractVector{<:Integer}) !isempty(degs) || return true # Check whether the sum of degrees is even iseven(sum(degs)) || return false - # Check that all degrees are non negative and less than n-1 + # Compute the length of the degree sequence n = length(degs) + # Check that all degrees are non negative and less than n-1 all(0 .<= degs .<= n - 1) || return false # Sort the degree sequence in non-increasing order sorted_degs = sort(degs; rev=true) - # Compute the length of the degree sequence + # Initialise a sum variable cur_sum = zero(UInt64) + right_deg_sum = zero(UInt64) + # Initalise a pointer to track the smallest index with degree greater than r + ptr = n # Check if the degree sequence satisfies the Erdös-Gallai condition @inbounds for r in 1:(n - 1) cur_sum += sorted_degs[r] - # Calculate the sum of the minimum of r and the degrees of the vertices - mid_deg_sum = sum([min(r, sorted_degs[i]) for i in (r + 1):n]) - cond = cur_sum <= (r * (r - 1) + mid_deg_sum) + # Calculate the sum of the minimum of r and the degrees of the vertices + min_idx = r + 1 + while ptr >= min_idx + if sorted_degs[ptr] <= r + # left_deg_sum = sum_{ptr+1}^n d_i + right_deg_sum += sorted_degs[ptr] + # move pointer to the 1-slot left + ptr -= 1 + else + # the ptr points to the degree greater than r + break + end + end + # calculate min_deg_sum: sum_{r+1}^n min(r, d_i) + if ptr < min_idx + # all required degrees are less than r + # ptr is min_idx - 1 + min_deg_sum = right_deg_sum + # prepare for the next iteration + # shift ptr to the right + ptr += 1 + # reduce right_deg_sum + right_deg_sum -= sorted_degs[ptr] + else + # d_i with i between ptr and min_idx are greater than r + min_deg_sum = (ptr - r) * r + right_deg_sum + end + # Check the Erdös-Gallai condition + cond = cur_sum <= (r * (r - 1) + min_deg_sum) cond || return false end return true From a803d32440baa743202b9906c015a266d5df8a0a Mon Sep 17 00:00:00 2001 From: ZHU Date: Tue, 18 Feb 2025 13:05:52 +0000 Subject: [PATCH 3/4] format --- src/connectivity.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/connectivity.jl b/src/connectivity.jl index a258e7fe7..2aae20364 100644 --- a/src/connectivity.jl +++ b/src/connectivity.jl @@ -820,7 +820,7 @@ function isgraphical(degs::AbstractVector{<:Integer}) right_deg_sum += sorted_degs[ptr] # move pointer to the 1-slot left ptr -= 1 - else + else # the ptr points to the degree greater than r break end From e715f106e9450f8a7a3dee00d1c2804d125ba382 Mon Sep 17 00:00:00 2001 From: Syuizen Date: Tue, 18 Feb 2025 13:12:11 +0000 Subject: [PATCH 4/4] format --- src/connectivity.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/connectivity.jl b/src/connectivity.jl index a258e7fe7..2aae20364 100644 --- a/src/connectivity.jl +++ b/src/connectivity.jl @@ -820,7 +820,7 @@ function isgraphical(degs::AbstractVector{<:Integer}) right_deg_sum += sorted_degs[ptr] # move pointer to the 1-slot left ptr -= 1 - else + else # the ptr points to the degree greater than r break end