Skip to content

Commit da8199d

Browse files
committed
getNeighborhood function
1 parent a462a0b commit da8199d

File tree

6 files changed

+108
-99
lines changed

6 files changed

+108
-99
lines changed

src/DFGPlots/DFGPlots.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ More information at [GraphPlot.jl](https://github.com/JuliaGraphs/GraphPlot.jl)
8888
function dfgplot(dfg::AbstractDFG, p::DFGPlotProps = DFGPlotProps())
8989
# TODO implement convert functions
9090
@warn "TODO Implement convert"
91-
ldfg = LightDFG{AbstractParams}()
91+
ldfg = LightDFG{NoSolverParams}()
9292
DistributedFactorGraphs._copyIntoGraph!(dfg, ldfg, union(getVariableIds(dfg), getFactorIds(dfg)), true, copyGraphMetadata=false)
9393

9494
dfgplot(ldfg, p)

src/GraphsDFG/services/GraphsDFG.jl

Lines changed: 35 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -327,40 +327,41 @@ function getNeighbors(dfg::GraphsDFG, label::Symbol; solvable::Int=0)::Vector{Sy
327327
return map(n -> n.dfgNode.label, neighbors)
328328
end
329329

330-
"""
331-
$(SIGNATURES)
332-
Retrieve a deep subgraph copy around a given variable or factor.
333-
Optionally provide a distance to specify the number of edges should be followed.
334-
Optionally provide an existing subgraph addToDFG, the extracted nodes will be copied into this graph. By default a new subgraph will be created.
335-
Note: By default orphaned factors (where the subgraph does not contain all the related variables) are not returned. Set includeOrphanFactors to return the orphans irrespective of whether the subgraph contains all the variables.
336-
"""
337-
function getSubgraphAroundNode(dfg::GraphsDFG{P}, node::T, distance::Int64=1, includeOrphanFactors::Bool=false, addToDFG::GraphsDFG=GraphsDFG{P}(); solvable::Int=0)::GraphsDFG where {P <: AbstractParams, T <: DFGNode}
338-
if !haskey(dfg.labelDict, node.label)
339-
error("Variable/factor with label '$(node.label)' does not exist in the factor graph")
340-
end
341-
342-
# Build a list of all unique neighbors inside 'distance'
343-
neighborList = Dict{Symbol, Any}()
344-
push!(neighborList, node.label => dfg.g.vertices[dfg.labelDict[node.label]])
345-
curList = Dict{Symbol, Any}(node.label => dfg.g.vertices[dfg.labelDict[node.label]])
346-
for dist in 1:distance
347-
newNeighbors = Dict{Symbol, Any}()
348-
for (key, node) in curList
349-
neighbors = in_neighbors(node, dfg.g) #Don't use out_neighbors! It enforces directiveness even if we don't want it
350-
for neighbor in neighbors
351-
if !haskey(neighborList, neighbor.dfgNode.label) && (isSolvable(neighbor.dfgNode) >= solvable)
352-
push!(neighborList, neighbor.dfgNode.label => neighbor)
353-
push!(newNeighbors, neighbor.dfgNode.label => neighbor)
354-
end
355-
end
356-
end
357-
curList = newNeighbors
358-
end
359-
360-
# Copy the section of graph we want
361-
_copyIntoGraph!(dfg, addToDFG, collect(keys(neighborList)), includeOrphanFactors)
362-
return addToDFG
363-
end
330+
#NOTE Replaced by abstract function in services/AbstractDFG.jl
331+
# """
332+
# $(SIGNATURES)
333+
# Retrieve a deep subgraph copy around a given variable or factor.
334+
# Optionally provide a distance to specify the number of edges should be followed.
335+
# Optionally provide an existing subgraph addToDFG, the extracted nodes will be copied into this graph. By default a new subgraph will be created.
336+
# Note: By default orphaned factors (where the subgraph does not contain all the related variables) are not returned. Set includeOrphanFactors to return the orphans irrespective of whether the subgraph contains all the variables.
337+
# """
338+
# function getSubgraphAroundNode(dfg::GraphsDFG{P}, node::T, distance::Int64=1, includeOrphanFactors::Bool=false, addToDFG::GraphsDFG=GraphsDFG{P}(); solvable::Int=0)::GraphsDFG where {P <: AbstractParams, T <: DFGNode}
339+
# if !haskey(dfg.labelDict, node.label)
340+
# error("Variable/factor with label '$(node.label)' does not exist in the factor graph")
341+
# end
342+
#
343+
# # Build a list of all unique neighbors inside 'distance'
344+
# neighborList = Dict{Symbol, Any}()
345+
# push!(neighborList, node.label => dfg.g.vertices[dfg.labelDict[node.label]])
346+
# curList = Dict{Symbol, Any}(node.label => dfg.g.vertices[dfg.labelDict[node.label]])
347+
# for dist in 1:distance
348+
# newNeighbors = Dict{Symbol, Any}()
349+
# for (key, node) in curList
350+
# neighbors = in_neighbors(node, dfg.g) #Don't use out_neighbors! It enforces directiveness even if we don't want it
351+
# for neighbor in neighbors
352+
# if !haskey(neighborList, neighbor.dfgNode.label) && (isSolvable(neighbor.dfgNode) >= solvable)
353+
# push!(neighborList, neighbor.dfgNode.label => neighbor)
354+
# push!(newNeighbors, neighbor.dfgNode.label => neighbor)
355+
# end
356+
# end
357+
# end
358+
# curList = newNeighbors
359+
# end
360+
#
361+
# # Copy the section of graph we want
362+
# _copyIntoGraph!(dfg, addToDFG, collect(keys(neighborList)), includeOrphanFactors)
363+
# return addToDFG
364+
# end
364365

365366
"""
366367
$(SIGNATURES)

src/LightDFG/entities/LightDFG.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ function LightDFG{T,V,F}(g::FactorGraph{Int,V,F}=FactorGraph{Int,V,F}();
3636
userData::Dict{Symbol, String} = Dict{Symbol, String}(),
3737
robotData::Dict{Symbol, String} = Dict{Symbol, String}(),
3838
sessionData::Dict{Symbol, String} = Dict{Symbol, String}(),
39-
params::T=NoSolverParams()) where {T <: AbstractParams, V <:AbstractDFGVariable, F<:AbstractDFGFactor}
39+
params::T=T()) where {T <: AbstractParams, V <:AbstractDFGVariable, F<:AbstractDFGFactor}
4040

4141
LightDFG{T,V,F}(g, description, userId, robotId, sessionId, userData, robotData, sessionData, Symbol[], params)
4242
end

src/SymbolDFG/services/SymbolDFG.jl

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -360,44 +360,44 @@ function _copyIntoGraph!(sourceDFG::SymbolDFG, destDFG::SymbolDFG, labels::Vecto
360360
return nothing
361361
end
362362

363-
364-
"""
365-
$(SIGNATURES)
366-
Retrieve a deep subgraph copy around a given variable or factor.
367-
Optionally provide a distance to specify the number of edges should be followed.
368-
Optionally provide an existing subgraph addToDFG, the extracted nodes will be copied into this graph. By default a new subgraph will be created.
369-
Note: By default orphaned factors (where the subgraph does not contain all the related variables) are not returned. Set includeOrphanFactors to return the orphans irrespective of whether the subgraph contains all the variables.
370-
"""
371-
function getSubgraphAroundNode(dfg::SymbolDFG, node::DFGNode, distance::Int64=1, includeOrphanFactors::Bool=false, addToDFG::SymbolDFG=SymbolDFG{AbstractParams}(); solvable::Int=0)::SymbolDFG
372-
if !exists(dfg,node.label)
373-
error("Variable/factor with label '$(node.label)' does not exist in the factor graph")
374-
end
375-
376-
nodelabel = node.label
377-
# Build a list of all unique neighbors inside 'distance'
378-
neighborList = Symbol[nodelabel]
379-
380-
curList = Symbol[nodelabel]
381-
382-
for dist in 1:distance
383-
newNeighbors = Symbol[]
384-
for cl in curList
385-
neighbors = outneighbors(dfg.g, cl)
386-
for neighbor in neighbors
387-
if !(neighbor in neighborList) && _isSolvable(dfg, neighbor, solvable)
388-
push!(neighborList, neighbor)
389-
push!(newNeighbors, neighbor)
390-
end
391-
end
392-
end
393-
curList = newNeighbors
394-
end
395-
396-
397-
# _copyIntoGraph!(dfg, addToDFG, map(n->get_prop(dfg.g, n, :label), ns), includeOrphanFactors)
398-
_copyIntoGraph!(dfg, addToDFG, neighborList, includeOrphanFactors)
399-
return addToDFG
400-
end
363+
# moved to abstract
364+
# """
365+
# $(SIGNATURES)
366+
# Retrieve a deep subgraph copy around a given variable or factor.
367+
# Optionally provide a distance to specify the number of edges should be followed.
368+
# Optionally provide an existing subgraph addToDFG, the extracted nodes will be copied into this graph. By default a new subgraph will be created.
369+
# Note: By default orphaned factors (where the subgraph does not contain all the related variables) are not returned. Set includeOrphanFactors to return the orphans irrespective of whether the subgraph contains all the variables.
370+
# """
371+
# function getSubgraphAroundNode(dfg::SymbolDFG, node::DFGNode, distance::Int64=1, includeOrphanFactors::Bool=false, addToDFG::SymbolDFG=SymbolDFG{AbstractParams}(); solvable::Int=0)::SymbolDFG
372+
# if !exists(dfg,node.label)
373+
# error("Variable/factor with label '$(node.label)' does not exist in the factor graph")
374+
# end
375+
#
376+
# nodelabel = node.label
377+
# # Build a list of all unique neighbors inside 'distance'
378+
# neighborList = Symbol[nodelabel]
379+
#
380+
# curList = Symbol[nodelabel]
381+
#
382+
# for dist in 1:distance
383+
# newNeighbors = Symbol[]
384+
# for cl in curList
385+
# neighbors = outneighbors(dfg.g, cl)
386+
# for neighbor in neighbors
387+
# if !(neighbor in neighborList) && _isSolvable(dfg, neighbor, solvable)
388+
# push!(neighborList, neighbor)
389+
# push!(newNeighbors, neighbor)
390+
# end
391+
# end
392+
# end
393+
# curList = newNeighbors
394+
# end
395+
#
396+
#
397+
# # _copyIntoGraph!(dfg, addToDFG, map(n->get_prop(dfg.g, n, :label), ns), includeOrphanFactors)
398+
# _copyIntoGraph!(dfg, addToDFG, neighborList, includeOrphanFactors)
399+
# return addToDFG
400+
# end
401401

402402

403403
"""

src/services/AbstractDFG.jl

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,30 @@ end
418418

419419
# TODO: NEED TO FIGURE OUT SIGNATURE FOR DEFAULT ARGS
420420

421+
422+
# TODO export, test and overwrite in LightGraphs and CloudGraphsDFG
423+
"""
424+
$(SIGNATURES)
425+
Build a list of all unique neighbors inside 'distance'
426+
"""
427+
function getNeighborhood(dfg::AbstractDFG, label::Symbol, distance::Int)::Vector{Symbol}
428+
neighborList = Set{Symbol}([label])
429+
curList = Set{Symbol}([label])
430+
431+
for dist in 1:distance
432+
newNeighbors = Set{Symbol}()
433+
for node in curList
434+
neighbors = getNeighbors(dfg, node)
435+
for neighbor in neighbors
436+
push!(neighborList, neighbor)
437+
push!(newNeighbors, neighbor)
438+
end
439+
end
440+
curList = newNeighbors
441+
end
442+
return collect(neighborList)
443+
end
444+
421445
"""
422446
$(SIGNATURES)
423447
Retrieve a deep subgraph copy around a given variable or factor.
@@ -426,35 +450,19 @@ Optionally provide an existing subgraph addToDFG, the extracted nodes will be co
426450
Note: By default orphaned factors (where the subgraph does not contain all the related variables) are not returned. Set includeOrphanFactors to return the orphans irrespective of whether the subgraph contains all the variables.
427451
Note: Always returns the node at the center, but filters around it if solvable is set.
428452
"""
429-
function getSubgraphAroundNode(dfg::G, node::T, distance::Int64=1, includeOrphanFactors::Bool=false, addToDFG::H=_getDuplicatedEmptyDFG(dfg); solvable::Int=0)::H where {G <: AbstractDFG, H <: AbstractDFG, P <: AbstractParams, T <: DFGNode}
430-
# error("getSubgraphAroundNode not implemented for $(typeof(dfg))")
453+
function getSubgraphAroundNode(dfg::AbstractDFG, node::DFGNode, distance::Int=1, includeOrphanFactors::Bool=false, addToDFG::AbstractDFG=_getDuplicatedEmptyDFG(dfg); solvable::Int=0)::AbstractDFG
454+
431455
if !exists(dfg, node.label)
432456
error("Variable/factor with label '$(node.label)' does not exist in the factor graph")
433457
end
434458

435-
# Build a list of all unique neighbors inside 'distance'
436-
neighborList = Dict{Symbol, Any}()
437-
push!(neighborList, node.label => getVariable(dfg, node.label))
438-
curList = Dict{Symbol, Any}(node.label => getVariable(dfg, node.label))
439-
for dist in 1:distance
440-
newNeighbors = Dict{Symbol, Any}()
441-
for (key, node) in curList
442-
neighbors = getNeighbors(dfg, node, solvable=solvable)
443-
for neighbor in neighbors
444-
if isVariable(dfg, neighbor)
445-
push!(neighborList, neighbor => getVariable(dfg,neighbor))
446-
push!(newNeighbors, neighbor => getVariable(dfg,neighbor))
447-
else
448-
push!(neighborList, neighbor => getFactor(dfg,neighbor))
449-
push!(newNeighbors, neighbor => getFactor(dfg,neighbor))
450-
end
451-
end
452-
end
453-
curList = newNeighbors
454-
end
459+
neighbors = getNeighborhood(dfg, node.label, distance)
460+
461+
# for some reason: always returns the node at the center with || (nlbl == node.label)
462+
solvable != 0 && filter!(nlbl -> (getSolvable(dfg, nlbl) >= solvable) || (nlbl == node.label), neighbors)
455463

456464
# Copy the section of graph we want
457-
_copyIntoGraph!(dfg, addToDFG, collect(keys(neighborList)), includeOrphanFactors)
465+
_copyIntoGraph!(dfg, addToDFG, neighbors, includeOrphanFactors)
458466
return addToDFG
459467
end
460468

test/interfaceTests.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -416,10 +416,10 @@ end
416416
# Filter - always returns the node you start at but filters around that.
417417
dfgSubgraph = getSubgraphAroundNode(dfg, getFactor(dfg, :x7x8f1), 1, true, solvable=1)
418418
@test symdiff([:x7x8f1, :x7], [ls(dfgSubgraph)..., lsf(dfgSubgraph)...]) == []
419-
# Test for distance = 2, so that it only returns chains with solvable=1 (not orphans)
419+
# Test for distance = 2, should return orphans
420420
#:x7x8f1 is not solvable
421421
dfgSubgraph = getSubgraphAroundNode(dfg, getVariable(dfg, :x8), 2, true, solvable=1)
422-
@test symdiff([:x8], [ls(dfgSubgraph)..., lsf(dfgSubgraph)...]) == []
422+
@test symdiff([:x8, :x7], [ls(dfgSubgraph)..., lsf(dfgSubgraph)...]) == []
423423

424424
# DFG issue #95 - confirming that getSubgraphAroundNode retains order
425425
# REF: https://github.com/JuliaRobotics/DistributedFactorGraphs.jl/issues/95

0 commit comments

Comments
 (0)