Skip to content

Commit

Permalink
Added clique_number, independence_number
Browse files Browse the repository at this point in the history
  • Loading branch information
dstahlke committed Feb 7, 2024
1 parent 42ba34e commit 470df1c
Show file tree
Hide file tree
Showing 7 changed files with 168 additions and 1 deletion.
5 changes: 5 additions & 0 deletions src/Graphs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,11 @@ export
triangles,
label_propagation,
maximal_cliques,
maximum_clique,
clique_number,
maximal_independent_sets,
maximum_independent_set,
independence_number,
clique_percolation,
assortativity,
rich_club,
Expand Down
116 changes: 116 additions & 0 deletions src/community/cliques.jl
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,119 @@ function maximal_cliques end
end
return cliques
end

"""
maximum_clique(g)
Return a vector representing the node indices of a maximum clique
of the undirected graph `g`.
```jldoctest
julia> using Graphs
julia> maximum_clique(blockdiag(complete_graph(3), complete_graph(4)))
4-element Vector{Int64}:
4
5
6
7
```
"""
function maximum_clique end
# see https://github.com/mauro3/SimpleTraits.jl/issues/47#issuecomment-327880153 for syntax
@traitfn function maximum_clique(g::AG::(!IsDirected)) where {T,AG<:AbstractGraph{T}}
return sort(argmax(length, maximal_cliques(g)))
end

"""
clique_number(g)
Returns the size of the largest clique of the undirected graph `g`.
```jldoctest
julia> using Graphs
julia> clique_number(blockdiag(complete_graph(3), complete_graph(4)))
4
```
"""
function clique_number end
# see https://github.com/mauro3/SimpleTraits.jl/issues/47#issuecomment-327880153 for syntax
@traitfn function clique_number(g::AG::(!IsDirected)) where {T,AG<:AbstractGraph{T}}
return maximum(length, maximal_cliques(g))
end

"""
maximal_independent_sets(g)
Return a vector of vectors representing the node indices in each of the maximal
independent sets found in the undirected graph `g`.
```jldoctest
julia> using Graphs
julia> maximal_independent_sets(cycle_graph(5))
5-element Vector{Vector{Int64}}:
[5, 2]
[5, 3]
[2, 4]
[1, 4]
[1, 3]
```
"""
function maximal_independent_sets end
# see https://github.com/mauro3/SimpleTraits.jl/issues/47#issuecomment-327880153 for syntax
@traitfn function maximal_independent_sets(
g::AG::(!IsDirected)
) where {T,AG<:AbstractGraph{T}}
# Convert to SimpleGraph first because `complement` doesn't accept AbstractGraph.
return maximal_cliques(complement(SimpleGraph(g)))
end

"""
maximum_independent_set(g)
Return a vector representing the node indices of a maximum independent set
of the undirected graph `g`.
### See also
[`independent_set`](@ref)
## Examples
```jldoctest
julia> using Graphs
julia> maximum_independent_set(cycle_graph(7))
3-element Vector{Int64}:
2
5
7
```
"""
function maximum_independent_set end
# see https://github.com/mauro3/SimpleTraits.jl/issues/47#issuecomment-327880153 for syntax
@traitfn function maximum_independent_set(
g::AG::(!IsDirected)
) where {T,AG<:AbstractGraph{T}}
# Convert to SimpleGraph first because `complement` doesn't accept AbstractGraph.
return maximum_clique(complement(SimpleGraph(g)))
end

"""
independence_number(g)
Returns the size of the largest independent set of the undirected graph `g`.
```jldoctest
julia> using Graphs
julia> independence_number(cycle_graph(7))
3
```
"""
function independence_number end
# see https://github.com/mauro3/SimpleTraits.jl/issues/47#issuecomment-327880153 for syntax
@traitfn function independence_number(g::AG::(!IsDirected)) where {T,AG<:AbstractGraph{T}}
# Convert to SimpleGraph first because `complement` doesn't accept AbstractGraph.
return clique_number(complement(SimpleGraph(g)))
end
3 changes: 3 additions & 0 deletions src/independentset/degree_ind_set.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ adjacent to the fewest valid vertices in the independent set until all vertices
### Performance
Runtime: O((|V|+|E|)*log(|V|))
Memory: O(|V|)
### See also
[`maximum_independent_set`](@ref)
"""
function independent_set(g::AbstractGraph{T}, alg::DegreeIndependentSet) where {T<:Integer}
nvg = nv(g)
Expand Down
3 changes: 3 additions & 0 deletions src/independentset/maximal_ind_set.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ Approximation Factor: maximum(degree(g))+1
### Optional Arguments
- `rng=nothing`: set the Random Number Generator.
- If `seed >= 0`, a random generator is seeded with this value.
### See also
[`maximum_independent_set`](@ref)
"""
function independent_set(
g::AbstractGraph{T},
Expand Down
7 changes: 6 additions & 1 deletion test/community/cliques.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@

function test_cliques(graph, expected)
# Make test results insensitive to ordering
return setofsets(@inferred(maximal_cliques(graph))) == setofsets(expected)
okay_maximal = setofsets(@inferred(maximal_cliques(graph))) == setofsets(expected)
okay_maximum = Set(@inferred(maximum_clique(graph))) in setofsets(expected)
okay_maximum2 =
length(@inferred(maximum_clique(graph))) == maximum(length.(expected))
okay_number = @inferred(clique_number(graph)) == maximum(length.(expected))
return okay_maximal && okay_maximum && okay_maximum2 && okay_number
end

gx = SimpleGraph(3)
Expand Down
34 changes: 34 additions & 0 deletions test/community/independent_sets.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
##################################################################
#
# Maximal independent sets of undirected graph
# Derived from Graphs.jl: https://github.com/julialang/Graphs.jl
#
##################################################################

@testset "Independent Sets" begin
function setofsets(array_of_arrays)
return Set(map(Set, array_of_arrays))
end

function test_independent_sets(graph, expected)
# Make test results insensitive to ordering
okay_maximal =
setofsets(@inferred(maximal_independent_sets(graph))) == setofsets(expected)
okay_maximum = Set(@inferred(maximum_independent_set(graph))) in setofsets(expected)
okay_maximum2 =
length(@inferred(maximum_independent_set(graph))) == maximum(length.(expected))
okay_number = @inferred(independence_number(graph)) == maximum(length.(expected))
return okay_maximal && okay_maximum && okay_maximum2 && okay_number
end

gx = SimpleGraph(3)
add_edge!(gx, 1, 2)
for g in test_generic_graphs(gx)
@test test_independent_sets(g, Array[[1, 3], [2, 3]])
end
add_edge!(gx, 2, 3)
for g in test_generic_graphs(gx)
@test test_independent_sets(g, Array[[1, 3], [2]])
end
@test independence_number(cycle_graph(11)) == 5
end
1 change: 1 addition & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ tests = [
"traversals/eulerian",
"community/cliques",
"community/core-periphery",
"community/independent_sets",
"community/label_propagation",
"community/modularity",
"community/clustering",
Expand Down

0 comments on commit 470df1c

Please sign in to comment.