过滤多个属性的顶点 - Julia

Filter vertices on several properties - Julia

我正在使用 Metagraphs.jl 库研究 julia。 为了进行优化问题,我想获得图中的 set/list 条边,这些边指向一组具有 2 个共同特定属性的特殊顶点。

我的第一个猜测是先得到顶点的set/list。但我面临第一个问题,即 filter_vertices 函数似乎不接受对多个 属性 应用过滤器。 以下是我想做的事情的示例:

g = DiGraph(5)
mg = MetaDiGraph(g, 1.0)

add_vertex!(mg)

add_edge!(mg,1,2)
add_edge!(mg,1,3)
add_edge!(mg,1,4)
add_edge!(mg,2,5)
add_edge!(mg,3,5)
add_edge!(mg,5,6)
add_edge!(mg,4,6)

set_props!(mg,3,Dict(:prop1=>1,:prop2=>2))

set_props!(mg,1,Dict(:prop1=>1,:prop2=>0))
set_props!(mg,2,Dict(:prop1=>1,:prop2=>0))
set_props!(mg,4,Dict(:prop1=>0,:prop2=>2))
set_props!(mg,5,Dict(:prop1=>0,:prop2=>2))
set_props!(mg,6,Dict(:prop1=>0,:prop2=>0))

col=collect(filter_vertices(mg,:prop1,1,:prop2,2))

而且我希望 col 找到顶点 3 而不是其他。

但是 filter_vertices 一次只能接受一个 属性 ,然后用 2 个过滤器进行循环然后尝试比较以便对列表进行排序会使成本更高具有这两个属性的顶点。

考虑到我的图表的大小,我想避免用多个昂贵的循环定义这个集合。你们中有人知道如何以一种简单而温和的方式解决这个问题吗?

我最后做了这个来回答我自己的问题:

fil3=Array{Int64,1}()
fil1=filter_vertices(mg,:prop1,1)
for f in fil1
    if get_prop(mg,f,:prop2)==2
        push!(fil3,f)
    end
end            
println(fil3)

但是如果你有什么更有趣的事情告诉我

感谢您的帮助!

我找到了这个解决方案:

function filter_function1(g,prop1,prop2)
  fil1=filter_vertices(g,:prop1,prop1)
  fil2=filter_vertices(g,:prop2,prop2)
  filter=intersect(fil1,fil2)
  return filter
end

这似乎可行并且很容易实现。 只是我不知道 filter_vertices 函数是否占用了大量计算能力。 否则像这样的简单循环似乎也有效:

function filter_function2(g,prop1,prop2)
  filter=Set{Int64}()
  fil1=filter_vertices(g,:prop1,prop1)
  for f in fil1
      if get_prop(g,f,:prop2)==prop2
          push!(filter,f)
      end
  end
  return filter
end

如果您有更优雅的答案,我愿意接受任何其他答案。

请以我们可以简单复制和粘贴的方式提供一个最小的工作示例,并立即开始。还请指出代码中出现问题的位置。以下是您的场景示例:

Pkg.add("MetaGraphs")

using LightGraphs, MetaGraphs

g = DiGraph(5)
mg = MetaDiGraph(g, 1.0)

add_vertex!(mg)

add_edge!(mg,1,2)
add_edge!(mg,1,3)
add_edge!(mg,1,4)
add_edge!(mg,2,5)
add_edge!(mg,3,5)
add_edge!(mg,5,6)
add_edge!(mg,4,6)

set_props!(mg,3,Dict(:prop1=>1,:prop2=>2))
set_props!(mg,1,Dict(:prop1=>1,:prop2=>0))
set_props!(mg,2,Dict(:prop1=>1,:prop2=>0))
set_props!(mg,4,Dict(:prop1=>0,:prop2=>2))
set_props!(mg,5,Dict(:prop1=>0,:prop2=>2))
set_props!(mg,6,Dict(:prop1=>0,:prop2=>0))

function my_vertex_filter(g::AbstractMetaGraph, v::Integer, prop1, prop2)
  return has_prop(g, v, :prop1) && get_prop(g, v, :prop1) == prop1 &&
         has_prop(g, v, :prop2) && get_prop(g, v, :prop2) == prop2
end

prop1 = 1
prop2 = 2

col = collect(filter_vertices(mg, (g,v)->my_vertex_filter(g,v,prop1,prop2)))
# returns Int[3]

请检查 ?filter_vertices --- 它会提示您 what/how 编写自定义过滤器。

编辑。 对于边缘过滤,您可以查看 ?filter_edges 以了解实现边缘过滤需要什么。将以下代码摘录附加到上面的解决方案以获得结果:

function my_edge_filter(g, e, prop1, prop2)
  v = dst(e) # get the edge's destination vertex
  return my_vertex_filter(g, v, prop1, prop2)
end

myedges = collect(filter_edges(mg, (g,e)->my_edge_filter(g,e,prop1,prop2)))
# returns [Edge 1 => 3]