Skip to content

Commit b14a8bb

Browse files
committed
find is the better verb as the path is still an index to the graph
1 parent c871442 commit b14a8bb

7 files changed

Lines changed: 66 additions & 59 deletions

File tree

src/Deprecated.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,7 @@ end
636636
# the `search` verb can also come ito play, but it is more for knn search type functions.
637637

638638
function findFactorsBetweenNaive(args...)
639-
return error("findFactorsBetweenNaive is obsolete, use DFG.getPath[s] instead.")
639+
return error("findFactorsBetweenNaive is obsolete, use DFG.findPath[s] instead.")
640640
end
641641

642642
#TODO deprecate `is` is the correct verb, but rather isHomogeneous(path::Path) the form is isAdjective
@@ -660,7 +660,7 @@ function isPathFactorsHomogeneous(dfg::AbstractDFG, from::Symbol, to::Symbol)
660660
return (length(utyp) == 1), utyp
661661
end
662662

663-
# deprecated use filter and path seperately.
663+
# deprecated use filter and path separately.
664664
function findShortestPathDijkstra(
665665
dfg::GraphsDFG,
666666
from::Symbol,
@@ -675,7 +675,7 @@ function findShortestPathDijkstra(
675675
initialized::Union{Nothing, Bool} = nothing,
676676
)
677677
Base.depwarn(
678-
"findShortestPathDijkstra is deprecated, use getPath with `variableLabels`/`factorLabels` kwargs instead.",
678+
"findShortestPathDijkstra is deprecated, use findPath with `variableLabels`/`factorLabels` kwargs instead.",
679679
:findShortestPathDijkstra,
680680
)
681681
any_active_filters = any(
@@ -710,8 +710,8 @@ function findShortestPathDijkstra(
710710
dfg,
711711
restrict_labels,
712712
)
713-
return getPath(subdfg, from, to).path
713+
return findPath(subdfg, from, to).path
714714
else
715-
return getPath(dfg, from, to).path
715+
return findPath(dfg, from, to).path
716716
end
717717
end

src/DistributedFactorGraphs.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -422,8 +422,8 @@ const unstable_functions::Vector{Symbol} = [
422422
:FactorSummary,
423423
:listNeighborhood,
424424
:listNeighbors,
425-
:getPath,
426-
:getPaths,
425+
:findPath,
426+
:findPaths,
427427
:InMemoryBlobstore,
428428
:exists,
429429
:compare,

src/GraphsDFG/GraphsDFG.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ import ...DistributedFactorGraphs:
5454
lsf,
5555
isConnected,
5656
listNeighbors,
57-
getPaths,
58-
getPath,
57+
findPaths,
58+
findPath,
5959
getSubgraph,
6060
getBiadjacencyMatrix,
6161
toDot,

src/GraphsDFG/services/GraphsDFG.jl

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -359,15 +359,15 @@ function toDot(dfg::GraphsDFG)
359359
end
360360

361361
#API design NOTE:
362-
# Do not create new Verbs or Nouns for metric vs. topological pathfinding. getPaths is the universal router... getPaths(..., metric)
362+
# Do not create new Verbs or Nouns for metric vs. topological pathfinding. findPaths is the universal router... findPaths(..., metric)
363363
# for now we only look at topological paths.
364364

365-
function getPaths(::typeof(all_simple_paths), dfg, from::Symbol, to::Symbol; kwargs...)
365+
function findPaths(::typeof(all_simple_paths), dfg, from::Symbol, to::Symbol; kwargs...)
366366
gpaths = Graphs.all_simple_paths(dfg.g, dfg.g.labels[from], dfg.g.labels[to]; kwargs...)
367367
return map(p -> (path = map(i -> dfg.g.labels[i], p), dist = length(p) - 1), gpaths)
368368
end
369369

370-
function getPaths(
370+
function findPaths(
371371
::typeof(yen_k_shortest_paths),
372372
dfg::GraphsDFG,
373373
from::Symbol,
@@ -390,12 +390,11 @@ function getPaths(
390390
end
391391

392392
# note with default heuristic this is just dijkstra's algorithm
393-
function getPaths(
393+
function findPaths(
394394
::typeof(a_star),
395395
dfg::GraphsDFG,
396396
from::Symbol,
397-
to::Symbol,
398-
::Int;
397+
to::Symbol;
399398
distmx::AbstractMatrix{T} = weights(dfg.g),
400399
heuristic = nothing,
401400
) where {T}
@@ -417,13 +416,12 @@ function getPaths(
417416
return [(path = path, dist = dist)]
418417
end
419418

420-
#TODO Move getPaths and getPath to AbstractDFG services as default implementations.
421-
function getPaths(
419+
#TODO Move findPaths and findPath to AbstractDFG services as default implementations.
420+
function findPaths(
422421
dfg::AbstractDFG,
423422
from::Symbol,
424423
to::Symbol,
425424
k::Int;
426-
algorithm = k == 1 ? a_star : yen_k_shortest_paths,
427425
variableLabels::Union{Nothing, Vector{Symbol}} = nothing,
428426
factorLabels::Union{Nothing, Vector{Symbol}} = nothing,
429427
kwargs...,
@@ -449,27 +447,29 @@ function getPaths(
449447
!hasFactor(active_dfg, to) &&
450448
throw(DFG.LabelNotFoundError(to))
451449

452-
return getPaths(algorithm, active_dfg, from, to, k; kwargs...)
450+
# optimization for k=1 since A* is more efficient than Yen's for single shortest path
451+
if k == 1
452+
return findPaths(a_star, active_dfg, from, to; kwargs...)
453+
else
454+
return findPaths(yen_k_shortest_paths, active_dfg, from, to, k; kwargs...)
455+
end
453456
end
454457

455-
function getPath(
458+
function findPath(
456459
dfg::AbstractDFG,
457460
from::Symbol,
458461
to::Symbol;
459462
variableLabels::Union{Nothing, Vector{Symbol}} = nothing,
460463
factorLabels::Union{Nothing, Vector{Symbol}} = nothing,
461464
kwargs...,
462465
)
463-
paths = getPaths(dfg, from, to, 1; variableLabels, factorLabels, kwargs...)
466+
paths = findPaths(dfg, from, to, 1; variableLabels, factorLabels, kwargs...)
464467

465-
# Adhere strictly to the "getSingular = Error" rule
466468
if isempty(paths)
467-
error(
468-
"No path found between :$(from) and :$(to). If a disconnected graph is expected, use `getPaths` instead.",
469-
)
469+
return nothing
470+
else
471+
return first(paths)
470472
end
471-
472-
return first(paths)
473473
end
474474

475475
export bfs_tree

src/entities/DFGVariable.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ end
2727
# TODO naming? Density, DensityRepresentation, BeliefRepresentation, BeliefState, etc?
2828
# TODO flatten in State? likeley not for easier serialization of points.
2929
@kwdef struct BeliefRepresentation{T <: StateType, P}
30-
statekind::T = T()# NOTE duplication for serialization, TODO maybe only in State and therefore belief cannot deserialize seperately.
30+
statekind::T = T()# NOTE duplication for serialization, TODO maybe only in State and therefore belief cannot deserialize separately.
3131
"""Discriminator for which representation is active."""
3232
densitykind::AbstractDensityKind = NonparametricDensityKind()
3333

src/services/AbstractDFG.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ Implement `listNeighbors(dfg::AbstractDFG, label::Symbol; solvableFilter, tagsFi
382382
function listNeighbors end
383383

384384
"""
385-
getPaths(dfg, from::Symbol, to::Symbol, k::Int; variableLabels, factorLabels, kwargs...)
385+
findPaths(dfg, from::Symbol, to::Symbol, k::Int; variableLabels, factorLabels, kwargs...)
386386
387387
Return the `k` shortest paths between `from` and `to` in the factor graph.
388388
Each result is a `(path = Vector{Symbol}, dist)` named tuple.
@@ -395,22 +395,22 @@ Typical usage with filters:
395395
```julia
396396
vars = listVariables(dfg; solvableFilter = >=(1))
397397
facs = listFactors(dfg; solvableFilter = >=(1))
398-
getPaths(dfg, :x1, :x5, 3; variableLabels = vars, factorLabels = facs)
398+
findPaths(dfg, :x1, :x5, 3; variableLabels = vars, factorLabels = facs)
399399
```
400400
401-
See also: [`getPath`](@ref), [`listVariables`](@ref), [`listFactors`](@ref)
401+
See also: [`findPath`](@ref), [`listVariables`](@ref), [`listFactors`](@ref)
402402
"""
403-
function getPaths end
403+
function findPaths end
404404

405405
"""
406-
getPath(dfg, from::Symbol, to::Symbol; variableLabels, factorLabels, kwargs...)
406+
findPath(dfg, from::Symbol, to::Symbol; variableLabels, factorLabels, kwargs...)
407407
408408
Return the single shortest path between `from` and `to`.
409-
Errors if no path exists (use `getPaths` for graphs that may be disconnected).
409+
Errors if no path exists (use `findPaths` for graphs that may be disconnected).
410410
411-
Accepts the same restriction keywords as [`getPaths`](@ref).
411+
Accepts the same restriction keywords as [`findPaths`](@ref).
412412
"""
413-
function getPath end
413+
function findPath end
414414

415415
function listNeighbors(dfg::AbstractDFG, node::AbstractGraphNode; kwargs...)
416416
return listNeighbors(dfg, getLabel(node); kwargs...)

test/testBlocks.jl

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1635,7 +1635,7 @@ function ProducingDotFiles(
16351635
# │ caller = ProducingDotFiles(testDFGAPI::Type{GraphsDFG}, v1::Nothing, v2::Nothing, f1::Nothing; VARTYPE::Type{VariableDFG}, FACTYPE::Type{FactorDFG}) at testBlocks.jl:1440
16361636
# └ @ Main ~/.julia/dev/DistributedFactorGraphs/test/testBlocks.jl:1440
16371637
addFactor!(dotdfg, f1)
1638-
#NOTE hardcoded toDot will have different results so test Graphs seperately
1638+
#NOTE hardcoded toDot will have different results so test Graphs separately
16391639
if testDFGAPI <: GraphsDFG || testDFGAPI <: GraphsDFG
16401640
todotstr = DFG.toDot(dotdfg)
16411641
todota =
@@ -1862,8 +1862,8 @@ function PathFindingTests(testDFGAPI)
18621862
addFactor!(dfg, FactorDFG(:x1x3f1, [:x1, :x3], TestFunctorInferenceType1()))
18631863
addFactor!(dfg, FactorDFG(:x2x4f1, [:x2, :x4], TestFunctorInferenceType1()))
18641864

1865-
# --- Basic getPaths / getPath (no restrictions) ---
1866-
result = getPath(dfg, :x1, :x3)
1865+
# --- Basic findPaths / findPath (no restrictions) ---
1866+
result = findPath(dfg, :x1, :x3)
18671867
# shortest path should be via the direct link x1-x1x3f1-x3 (dist=2) not via x2 (dist=4)
18681868
@test result.path == [:x1, :x1x3f1, :x3]
18691869
@test result.dist == 2
@@ -1873,19 +1873,19 @@ function PathFindingTests(testDFGAPI)
18731873
# 2) x1-x1x3f1-x3-x3x4f1-x4 (dist=4)
18741874
# 3) x1-x1x2f1-x2-x2x3f1-x3-x3x4f1-x4 (dist=6)
18751875
# 4) x1-x1x3f1-x3-x2x3f1-x2-x2x4f1-x4 (dist=6)
1876-
results = getPaths(dfg, :x1, :x4, 4)
1876+
results = findPaths(dfg, :x1, :x4, 4)
18771877
@test length(results) >= 2
18781878
@test results[1].dist <= results[end].dist # sorted by distance
18791879

18801880
# path across the whole graph
1881-
full_path = getPath(dfg, :x1, :x10)
1881+
full_path = findPath(dfg, :x1, :x10)
18821882
@test :x1 == first(full_path.path)
18831883
@test :x10 == last(full_path.path)
18841884

18851885
# --- Restrict with variableLabels only (all factors kept) ---
18861886
# Restrict to x1..x5 variables. Factors connecting only those vars are auto-included.
18871887
vars_subset = listVariables(dfg; typeFilter = ==(TestVariableType1()))
1888-
result_restricted = getPath(dfg, :x1, :x5; variableLabels = vars_subset)
1888+
result_restricted = findPath(dfg, :x1, :x5; variableLabels = vars_subset)
18891889
@test first(result_restricted.path) == :x1
18901890
@test last(result_restricted.path) == :x5
18911891
# x6..x10 should NOT appear on the path
@@ -1894,15 +1894,15 @@ function PathFindingTests(testDFGAPI)
18941894
# --- Restrict with factorLabels only (all variables kept) ---
18951895
# Only allow the first 4 factors, path x1→x5 should still work
18961896
facs_first4 = listFactors(dfg; labelFilter = contains(r"x[1-4](?!\d)"))
1897-
result_fac = getPath(dfg, :x1, :x5; factorLabels = facs_first4)
1897+
result_fac = findPath(dfg, :x1, :x5; factorLabels = facs_first4)
18981898
@test first(result_fac.path) == :x1
18991899
@test last(result_fac.path) == :x5
19001900

19011901
# --- Restrict with both variableLabels and factorLabels ---
19021902
vars_1to5 = listVariables(dfg; typeFilter = ==(TestVariableType1()))
19031903
facs_1to4 = listFactors(dfg; labelFilter = contains(r"x[1-4](?!\d)"))
19041904
result_both =
1905-
getPath(dfg, :x1, :x5; variableLabels = vars_1to5, factorLabels = facs_1to4)
1905+
findPath(dfg, :x1, :x5; variableLabels = vars_1to5, factorLabels = facs_1to4)
19061906
@test first(result_both.path) == :x1
19071907
@test last(result_both.path) == :x5
19081908

@@ -1911,16 +1911,21 @@ function PathFindingTests(testDFGAPI)
19111911
solvable_vars = listVariables(dfg; solvableFilter = >=(1))
19121912
solvable_facs = listFactors(dfg; solvableFilter = >=(1))
19131913
# Path from x1 to x7 should work (all solvable)
1914-
result_solvable =
1915-
getPath(dfg, :x1, :x7; variableLabels = solvable_vars, factorLabels = solvable_facs)
1914+
result_solvable = findPath(
1915+
dfg,
1916+
:x1,
1917+
:x7;
1918+
variableLabels = solvable_vars,
1919+
factorLabels = solvable_facs,
1920+
)
19161921
@test first(result_solvable.path) == :x1
19171922
@test last(result_solvable.path) == :x7
19181923
# x8 and x9 (unsolvable) should not appear
19191924
@test :x8 result_solvable.path
19201925
@test :x9 result_solvable.path
19211926

19221927
# Path from x1 to x10 with solvable filter should fail (x8, x9, x7x8f1 block the way)
1923-
paths_blocked = getPaths(
1928+
paths_blocked = findPaths(
19241929
dfg,
19251930
:x1,
19261931
:x10,
@@ -1930,13 +1935,15 @@ function PathFindingTests(testDFGAPI)
19301935
)
19311936
@test isempty(paths_blocked)
19321937

1933-
# And the singular getPath should throw on disconnect
1934-
@test_throws ErrorException getPath(
1935-
dfg,
1936-
:x1,
1937-
:x10;
1938-
variableLabels = solvable_vars,
1939-
factorLabels = solvable_facs,
1938+
# And the singular findPath should return nothing
1939+
@test isnothing(
1940+
findPath(
1941+
dfg,
1942+
:x1,
1943+
:x10;
1944+
variableLabels = solvable_vars,
1945+
factorLabels = solvable_facs,
1946+
),
19401947
)
19411948

19421949
# --- With tagsFilter ---
@@ -1948,15 +1955,15 @@ function PathFindingTests(testDFGAPI)
19481955
@test :x4 landmark_vars
19491956
# Restrict to only LANDMARK variables - x1 is not a LANDMARK, so include it to enable the path
19501957
vars_with_x1 = union([:x1, :x2], landmark_vars)
1951-
result_tags = getPath(dfg, :x1, :x4; variableLabels = vars_with_x1)
1958+
result_tags = findPath(dfg, :x1, :x4; variableLabels = vars_with_x1)
19521959
@test first(result_tags.path) == :x1
19531960
@test last(result_tags.path) == :x4
19541961
# x5..x10 should not be on this path
19551962
@test isempty(intersect(result_tags.path, [:x5, :x6, :x7, :x8, :x9, :x10]))
19561963

1957-
# --- getPaths with k > 1 on looped graph ---
1964+
# --- findPaths with k > 1 on looped graph ---
19581965
# With cross-links x1x3f1 and x2x4f1. Multiple paths exist from x1 to x4.
1959-
results_multi = getPaths(dfg, :x1, :x4, 5)
1966+
results_multi = findPaths(dfg, :x1, :x4, 5)
19601967
@test length(results_multi) >= 2
19611968
# All paths should start at x1 and end at x4
19621969
for r in results_multi
@@ -1969,7 +1976,7 @@ function PathFindingTests(testDFGAPI)
19691976
# --- Error: no path exists ---
19701977
# Disconnect x10 by removing the factor
19711978
deleteFactor!(dfg, :x9x10f1)
1972-
@test_throws ErrorException getPath(dfg, :x1, :x10)
1973-
empty_paths = getPaths(dfg, :x1, :x10, 1)
1979+
@test isnothing(findPath(dfg, :x1, :x10))
1980+
empty_paths = findPaths(dfg, :x1, :x10, 1)
19741981
@test isempty(empty_paths)
19751982
end

0 commit comments

Comments
 (0)