Skip to content

Commit 287a462

Browse files
committed
Add function treefill. Also,
- improve performance of algorithm `ND` - expand type union `PermutationOrAlgorithm` - improve code coverage
1 parent 7cb0c43 commit 287a462

14 files changed

Lines changed: 1140 additions & 414 deletions

src/CliqueTrees.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ export BFS,
6666
SafeSeparators,
6767
ConnectedComponents,
6868
BestWidth,
69+
BestFill,
6970
permutation,
7071
mcs
7172

@@ -82,7 +83,7 @@ export SupernodeTree, supernodetree, residuals
8283
export Clique, separator, residual
8384

8485
# Clique Trees
85-
export CliqueTree, cliquetree, treewidth, separators, relatives
86+
export CliqueTree, cliquetree, treewidth, treefill, separators, relatives
8687

8788
# Abstract Trees
8889
export firstchildindex, rootindices, ancestorindices

src/Utilities.jl/src/Utilities.jl

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ using Base.Order
66
using Graphs
77

88
# arithmetic
9-
export tolerance, twice, half, two, three, four, ispositive, isnegative, istwo, isthree
9+
export tolerance, twice, half, two, three, four, ispositive, isnegative, istwo, isthree, isfour
1010

1111
# graphs
1212
export eltypedegree, de
@@ -71,6 +71,10 @@ function isnegative(i::I) where {I}
7171
return i < zero(I)
7272
end
7373

74+
function isfour(i::I) where {I}
75+
return i == four(I)
76+
end
77+
7478
function isthree(i::I) where {I}
7579
return i == three(I)
7680
end
@@ -174,13 +178,33 @@ end
174178
end
175179

176180
function printiterator(io::IO, iterator::T) where {T}
181+
return printiterator(io, iterator, Base.IteratorSize(T))
182+
end
183+
184+
function printiterator(io::IO, iterator::T, ::Any) where {T}
177185
print(io, "$T:")
186+
printelements(io, iterator)
187+
return
188+
end
189+
190+
function printiterator(io::IO, iterator::T, ::Base.HasLength) where {T}
191+
n = length(iterator)
192+
print(io, "$n-element $T:")
193+
printelements(io, iterator)
194+
return
195+
end
196+
197+
function printelements(io::IO, iterator)
198+
count = 0
199+
200+
for v in iterator
201+
count += 1
178202

179-
for (i, v) in enumerate(take(iterator, MAX_ITEMS_PRINTED + 1))
180-
if i <= MAX_ITEMS_PRINTED
203+
if count <= MAX_ITEMS_PRINTED
181204
print(io, "\n $v")
182205
else
183206
print(io, "\n")
207+
break
184208
end
185209
end
186210

src/ambiguities.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1+
# ---------- #
2+
# lowerbound #
3+
# ---------- #
4+
lowerbound(weights::AbstractVector, ::Number) = error()
5+
lowerbound(weights::AbstractVector, ::MMW) = error()
6+
17
# ----------- #
28
# permutation #
39
# ----------- #
410

511
permutation(weights::AbstractVector, alg::EliminationAlgorithm) = error()
612
permutation(weights::AbstractVector, alg::AbstractVector) = error()
13+
permutation(weights::AbstractVector, alg::Tuple{AbstractVector, AbstractVector}) = error()
714
permutation(weights::AbstractVector, alg::BFS) = error()
815
permutation(weights::AbstractVector, alg::MCS) = error()
916
permutation(weights::AbstractVector, alg::LexBFS) = error()
@@ -27,6 +34,7 @@ permutation(weights::AbstractVector, alg::SafeRules) = error()
2734
permutation(weights::AbstractVector, alg::SafeSeparators) = error()
2835
permutation(weights::AbstractVector, alg::ConnectedComponents) = error()
2936
permutation(weights::AbstractVector, alg::BestWidth) = error()
37+
permutation(weights::AbstractVector, alg::BestFill) = error()
3038

3139
# --------------- #
3240
# eliminationtree #
@@ -39,3 +47,9 @@ eliminationtree(weights::AbstractVector, alg::PermutationOrAlgorithm) = error()
3947
# --------- #
4048

4149
treewidth(weights::AbstractVector, alg::PermutationOrAlgorithm) = error()
50+
51+
# -------- #
52+
# treefill #
53+
# -------- #
54+
55+
treefill(weights::AbstractVector, alg::PermutationOrAlgorithm) = error()

src/bipartite_edge_iter.jl

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,8 @@ struct BipartiteEdgeIter{V, E, Ptr, Tgt} <: AbstractEdgeIter
22
graph::BipartiteGraph{V, E, Ptr, Tgt}
33
end
44

5-
function Base.show(io::IO, iter::I) where {I <: BipartiteEdgeIter}
6-
n = length(iter)
7-
println(io, "$n-element $I:")
8-
9-
for (i, edge) in enumerate(take(iter, MAX_ITEMS_PRINTED + 1))
10-
if i <= MAX_ITEMS_PRINTED
11-
println(io, " $edge")
12-
else
13-
println(io, "")
14-
end
15-
end
5+
function Base.show(io::IO, iter::BipartiteEdgeIter)
6+
printiterator(io, iter)
167
return
178
end
189

@@ -32,22 +23,30 @@ end
3223
# Iteration Interface #
3324
#######################
3425

35-
function Base.iterate(
36-
iter::BipartiteEdgeIter{V, E}, (i, p)::Tuple{V, E} = (one(V), one(E))
37-
) where {V, E}
38-
return if p <= length(iter)
39-
edge = SimpleEdge{V}(i, targets(iter.graph)[p])
26+
function Base.iterate(iter::BipartiteEdgeIter{V, E}, (i, p)::Tuple{V, E} = (one(V), one(E))) where {V, E}
27+
graph = iter.graph; ii = i + one(V); pp = p + one(E)
28+
result = nothing
4029

41-
j = i + one(V)
42-
q = p + one(E)
43-
state = q < pointers(iter.graph)[j] ? (i, q) : (j, q)
30+
if p <= ne(graph)
31+
@inbounds j = targets(graph)[p]
32+
@inbounds qq = pointers(graph)[ii]
33+
edge = SimpleEdge{V}(i, j)
4434

45-
edge, state
35+
if pp < qq
36+
state = (i, pp)
37+
else
38+
state = (ii, pp)
39+
end
40+
41+
result = (edge, state)
4642
end
43+
44+
return result
4745
end
4846

4947
function Base.length(iter::BipartiteEdgeIter)
50-
return ne(iter.graph)
48+
m::Int = ne(iter.graph)
49+
return m
5150
end
5251

5352
function Base.eltype(::Type{<:BipartiteEdgeIter{V}}) where {V}

src/bipartite_graphs.jl

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -229,12 +229,20 @@ function sympermute!(
229229
index::AbstractVector,
230230
order::Ordering,
231231
) where {V, E}
232-
# validate arguments
233232
@argcheck vertices(graph) == vertices(result)
234233
@argcheck vertices(graph) == eachindex(index)
234+
count = Vector{E}(undef, nv(graph) + one(V))
235+
return sympermute!(count, result, graph, index, order)
236+
end
235237

238+
function sympermute!(
239+
count::Vector{E},
240+
result::BipartiteGraph{V, E},
241+
graph::AbstractGraph,
242+
index::AbstractVector,
243+
order::Ordering,
244+
) where {V, E}
236245
# compute column counts
237-
count = Vector{E}(undef, nv(graph) + one(V))
238246
count[one(V)] = one(E)
239247
count[two(V):(nv(graph) + one(V))] .= zero(E)
240248

@@ -286,9 +294,12 @@ function Base.reverse!(result::BipartiteGraph{V, E}, graph::AbstractGraph{V}) wh
286294
@argcheck nv(graph) == nov(result)
287295
@argcheck ne(graph) == ne(result)
288296
@argcheck nov(graph) == nv(result)
297+
count = Vector{E}(undef, nov(graph) + one(V))
298+
return reverse!(count, result, graph)
299+
end
289300

301+
function Base.reverse!(count::Vector{E}, result::BipartiteGraph{V, E}, graph::AbstractGraph{V}) where {V, E}
290302
# compute column counts
291-
count = Vector{E}(undef, nov(graph) + one(V))
292303
count[one(V)] = one(E)
293304
count[two(V):(nov(graph) + one(V))] .= zero(E)
294305

@@ -444,12 +455,13 @@ function Graphs.vertices(graph::BipartiteGraph{V}) where {V}
444455
return oneto(nv(graph))
445456
end
446457

447-
@propagate_inbounds function Graphs.outneighbors(
448-
graph::BipartiteGraph{<:Any, E}, i::Integer
449-
) where {E}
458+
@propagate_inbounds function Graphs.outneighbors(graph::BipartiteGraph{<:Any, E}, i::I) where {E, I <: Integer}
459+
ii = i + one(I)
450460
@boundscheck checkbounds(pointers(graph), i)
451-
@boundscheck checkbounds(pointers(graph), i + 1)
452-
return @inbounds @view targets(graph)[pointers(graph)[i]:(pointers(graph)[i + 1] - one(E))]
461+
@boundscheck checkbounds(pointers(graph), ii)
462+
@inbounds p = pointers(graph)[i]
463+
@inbounds pp = pointers(graph)[ii]
464+
return @view targets(graph)[p:(pp - one(E))]
453465
end
454466

455467
# slow
@@ -459,23 +471,24 @@ function Graphs.inneighbors(graph::BipartiteGraph, i::Integer)
459471
end
460472
end
461473

462-
@propagate_inbounds function Graphs.outdegree(
463-
graph::BipartiteGraph{V}, i::Integer
464-
) where {V}
474+
@propagate_inbounds function Graphs.outdegree(graph::BipartiteGraph, i::I) where {I <: Integer}
475+
ii = i + one(I)
465476
@boundscheck checkbounds(pointers(graph), i)
466-
@boundscheck checkbounds(pointers(graph), i + 1)
467-
@inbounds n::V = pointers(graph)[i + 1] - pointers(graph)[i]
477+
@boundscheck checkbounds(pointers(graph), ii)
478+
@inbounds p = pointers(graph)[i]
479+
@inbounds pp = pointers(graph)[ii]
480+
n::Int = pp - p
468481
return n
469482
end
470483

471484
# slow
472485
function Graphs.indegree(graph::BipartiteGraph{V}, i::Integer) where {V}
473-
n::V = sum(j -> has_edge(graph, j, i), vertices(graph))
486+
n::Int = sum(j -> has_edge(graph, j, i), vertices(graph))
474487
return n
475488
end
476489

477-
function Graphs.Δout(graph::BipartiteGraph{V}) where {V}
478-
return maximum(vertices(graph); init = zero(V)) do i
490+
function Graphs.Δout(graph::BipartiteGraph)
491+
return maximum(vertices(graph); init = 0) do i
479492
outdegree(graph, i)
480493
end
481494
end

src/chordal_graphs.jl

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,18 @@ end
2929
function isperfect(
3030
graph::AbstractGraph{V}, order::AbstractVector{V}, index::AbstractVector{V}
3131
) where {V}
32+
n = nv(graph)
33+
3234
# validate arguments
3335
@argcheck vertices(graph) == eachindex(index)
3436
@argcheck vertices(graph) == eachindex(order)
3537

3638
# run algorithm
37-
f = Vector{V}(undef, nv(graph))
38-
findex = Vector{V}(undef, nv(graph))
39+
f = Vector{V}(undef, n)
40+
findex = Vector{V}(undef, n)
3941

40-
for (i, w) in enumerate(order)
41-
f[w] = w
42-
findex[w] = i
42+
for i in oneto(n)
43+
w = order[i]; f[w] = w; findex[w] = i
4344

4445
for v in neighbors(graph, w)
4546
if index[v] < i

0 commit comments

Comments
 (0)