过滤几个属性上的顶点 - Julia

问题描述 投票:1回答:2

我正在使用Metagraphs.jl库与julia合作。为了进行优化问题,我想得到图中边缘的集合/列表,指向一组特殊的顶点,这些顶点具有两个共同的特定属性。

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

但是告诉我你是否有更多有趣的东西

谢谢你的帮助!

graph filter julia vertex
2个回答
2
投票

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

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]

0
投票

我发现这个解决方案:

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

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

© www.soinside.com 2019 - 2024. All rights reserved.