Skip to content

Commit c5aca53

Browse files
committed
improve isgraphical from O(n^2) to O(n*log(n))
1 parent c378d9f commit c5aca53

File tree

1 file changed

+35
-5
lines changed

1 file changed

+35
-5
lines changed

src/connectivity.jl

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -798,19 +798,49 @@ function isgraphical(degs::AbstractVector{<:Integer})
798798
!isempty(degs) || return true
799799
# Check whether the sum of degrees is even
800800
iseven(sum(degs)) || return false
801-
# Check that all degrees are non negative and less than n-1
801+
# Compute the length of the degree sequence
802802
n = length(degs)
803+
# Check that all degrees are non negative and less than n-1
803804
all(0 .<= degs .<= n - 1) || return false
804805
# Sort the degree sequence in non-increasing order
805806
sorted_degs = sort(degs; rev=true)
806-
# Compute the length of the degree sequence
807+
# Initialise a sum variable
807808
cur_sum = zero(UInt64)
809+
right_deg_sum = zero(UInt64)
810+
# Initalise a pointer to track the smallest index with degree greater than r
811+
ptr = n
808812
# Check if the degree sequence satisfies the Erdös-Gallai condition
809813
@inbounds for r in 1:(n - 1)
810814
cur_sum += sorted_degs[r]
811-
# Calculate the sum of the minimum of r and the degrees of the vertices
812-
mid_deg_sum = sum([min(r, sorted_degs[i]) for i in (r + 1):n])
813-
cond = cur_sum <= (r * (r - 1) + mid_deg_sum)
815+
# Calculate the sum of the minimum of r and the degrees of the vertices
816+
min_idx = r + 1
817+
while ptr >= min_idx
818+
if sorted_degs[ptr] <= r
819+
# left_deg_sum = sum_{ptr+1}^n d_i
820+
right_deg_sum += sorted_degs[ptr]
821+
# move pointer to the 1-slot left
822+
ptr -= 1
823+
else
824+
# the ptr points to the degree greater than r
825+
break
826+
end
827+
end
828+
# calculate min_deg_sum: sum_{r+1}^n min(r, d_i)
829+
if ptr < min_idx
830+
# all required degrees are less than r
831+
# ptr is min_idx - 1
832+
min_deg_sum = right_deg_sum
833+
# prepare for the next iteration
834+
# shift ptr to the right
835+
ptr += 1
836+
# reduce right_deg_sum
837+
right_deg_sum -= sorted_degs[ptr]
838+
else
839+
# d_i with i between ptr and min_idx are greater than r
840+
min_deg_sum = (ptr - r) * r + right_deg_sum
841+
end
842+
# Check the Erdös-Gallai condition
843+
cond = cur_sum <= (r * (r - 1) + min_deg_sum)
814844
cond || return false
815845
end
816846
return true

0 commit comments

Comments
 (0)