繁体   English   中英

过滤多个属性上的顶点-朱莉娅

[英]Filter vertices on several properties - Julia

我正在使用Metagraphs.jl库从事Metagraphs.jl工作。 为了进行优化问题,我想获得图中的一组边/列表,这些边/列表指向一组具有2个特定公共属性的特殊顶点。

我的第一个猜测是首先获取顶点集/列表。 但是我面临的第一个问题是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)

但请告诉我您是否还有其他有趣的事情

谢谢你的帮助!

请以我们可以简单地复制和粘贴并立即开始的方式提供一个最小的工作示例。 另请在代码中指出问题出在哪里。 以下是您的方案的示例:

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 ---它为您提供有关定义自定义过滤器的内容的提示。

编辑。 要过滤边缘,您可以查看?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]

我找到了这个解决方案:

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

如果您有其他更优雅的答案,我也欢迎您提出其他答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM