julia中边上的条件和

julia中边上的条件和,julia,list-comprehension,Julia,List Comprehension,我有一个复杂的问题,我必须从先前构建的图中计算边上的和。 Julia似乎不会处理带边的条件和 下面是一个与我试图解决的问题类似的简单问题: module EssaiModule using LightGraphs, MetaGraphs g = DiGraph(6) 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,4) a

我有一个复杂的问题,我必须从先前构建的图中计算边上的和。 Julia似乎不会处理带边的条件和

下面是一个与我试图解决的问题类似的简单问题:

module EssaiModule

using LightGraphs, MetaGraphs

g = DiGraph(6)
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,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(:port=>1,:vessel=>2))
set_props!(mg,1,Dict(:port=>1,:vessel=>0))
set_props!(mg,2,Dict(:port=>1,:vessel=>0))
set_props!(mg,4,Dict(:port=>1,:vessel=>2))
set_props!(mg,5,Dict(:port=>0,:vessel=>2))
set_props!(mg,6,Dict(:port=>0,:vessel=>0))

SI = sum(1 for e in edges(mg);get_prop(g,dst(e),:vessel)==2 && get_prop(g,dst(e),:port)==1)

println(SI)

end
当我这样测试它时,我得到了错误

#LoadError: MethodError: no method matching dst(::Irrational{:e})
我真的需要弄清楚如何用条件求和,因为在我的实际问题中,我把这个和放在一个约束中,就像这样,边上的和
ed
x
是一个变量:

@constraint(model, cM[e in edges(g)], x[e] + sum(x[ed] for ed in edges(g) ; fn1(ed) == 2 && fn2(ed) == 1) <= 1 + y)
因此,我的问题如下:

  • 既然
    e
    的类型是
    Int
    ,为什么第一个代码不起作用

  • 我是否以一种糟糕的方式编写约束


  • 很抱歉,我无法上传真正的问题,内容和数据不能放在网上,而且太大。

    对于问题的第一部分,您需要更改函数调用

    SI = sum(1 for e in edges(mg);get_prop(g,dst(e),:vessel)==2 && get_prop(g,dst(e),:port)==1)
    #                            ^ you end the statement with a semicolon
    # after the semicolon, keyword arguments of a function, in this case `sum`,
    # begins. then, the compiler checks the function `dst` and cannot find a proper
    # method that is implemented for e, that is, the irrational number e.
    
    全文如下:

    SI = length([e for e in edges(mg) if get_prop(mg, dst(e), :vessel) == 2 &&
                                         get_prop(mg, dst(e), :port  ) == 1   ])
    
    println(SI) # prints 3
    
    还要注意代码中的输入错误
    get_prop
    需要检查
    mg
    ,而不是
    g
    。您还应该看看文档中的部分

    对于问题的第二部分,您应该为我们提供宏观定义,以便更好地帮助您。很可能,您不是宏中的表达式/变量。看一个不同的问题,并告诉如果这有帮助

    编辑1。实际上,你的第二部分也有同样的问题。在
    sum
    中,用分号结束位置参数,并启动

    编辑2。根据DNF下面的评论,您甚至应该使用
    count
    来获得更具表现力(源代码)和效率的版本:

    SI = count(e->(get_prop(mg, dst(e), :vessel) == 2 &&
                   get_prop(mg, dst(e), :port  ) == 1   ), edges(mg))
    # or,
    SI = count(get_prop(mg, dst(e), :vessel) == 2 &&
               get_prop(mg, dst(e), :port  ) == 1    for e in edges(mg))
    
    编辑3。性能比较如下:

    Pkg.add("BenchmarkTools")
    using BenchmarkTools
    
    @benchmark count(e->(get_prop(mg, dst(e), :vessel) == 2 &&
                         get_prop(mg, dst(e), :port  ) == 1   ), edges(mg))
    
    BenchmarkTools.Trial:
      memory estimate:  7.73 KiB
      allocs estimate:  53
      --------------
      minimum time:     2.201 μs (0.00% GC)
      median time:      2.494 μs (0.00% GC)
      mean time:        3.191 μs (15.69% GC)
      maximum time:     198.515 μs (95.69% GC)
      --------------
      samples:          10000
      evals/sample:     9
    
    @benchmark count(get_prop(mg, dst(e), :vessel) == 2 &&
                     get_prop(mg, dst(e), :port  ) == 1    for e in edges(mg))
    
    BenchmarkTools.Trial:
      memory estimate:  7.75 KiB
      allocs estimate:  54
      --------------
      minimum time:     2.352 μs (0.00% GC)
      median time:      2.661 μs (0.00% GC)
      mean time:        3.712 μs (15.10% GC)
      maximum time:     236.440 μs (95.06% GC)
      --------------
      samples:          10000
      evals/sample:     9
    
    @benchmark length([e for e in edges(mg) if get_prop(mg, dst(e), :vessel) == 2 &&
                                               get_prop(mg, dst(e), :port  ) == 1])
    
    BenchmarkTools.Trial:
      memory estimate:  8.13 KiB
      allocs estimate:  60
      --------------
      minimum time:     2.642 μs (0.00% GC)
      median time:      2.789 μs (0.00% GC)
      mean time:        3.553 μs (14.54% GC)
      maximum time:     231.424 μs (94.73% GC)
      --------------
      samples:          10000
      evals/sample:     9
    
    count
    版本的效率似乎比
    length
    高10%,这可能会对您的实际更大问题产生影响

    编辑4。由于DNF,进行基准测试的正确方法如下:

    @benchmark count(e->(get_prop($mg, dst(e), :vessel) == 2 &&
                         get_prop($mg, dst(e), :port  ) == 1   ), edges($mg))
    
    BenchmarkTools.Trial:
      memory estimate:  7.72 KiB
      allocs estimate:  52
      --------------
      minimum time:     2.320 μs (0.00% GC)
      median time:      2.478 μs (0.00% GC)
      mean time:        2.952 μs (10.33% GC)
      maximum time:     117.306 μs (93.38% GC)
      --------------
      samples:          10000
      evals/sample:     9
    
    @benchmark count(get_prop($mg, dst(e), :vessel) == 2 &&
                     get_prop($mg, dst(e), :port  ) == 1    for e in edges($mg))
    
    BenchmarkTools.Trial:
      memory estimate:  7.73 KiB
      allocs estimate:  53
      --------------
      minimum time:     2.340 μs (0.00% GC)
      median time:      2.524 μs (0.00% GC)
      mean time:        3.030 μs (11.17% GC)
      maximum time:     197.018 μs (94.35% GC)
      --------------
      samples:          10000
      evals/sample:     9
    

    对于问题的第一部分,您需要更改函数调用

    SI = sum(1 for e in edges(mg);get_prop(g,dst(e),:vessel)==2 && get_prop(g,dst(e),:port)==1)
    #                            ^ you end the statement with a semicolon
    # after the semicolon, keyword arguments of a function, in this case `sum`,
    # begins. then, the compiler checks the function `dst` and cannot find a proper
    # method that is implemented for e, that is, the irrational number e.
    
    全文如下:

    SI = length([e for e in edges(mg) if get_prop(mg, dst(e), :vessel) == 2 &&
                                         get_prop(mg, dst(e), :port  ) == 1   ])
    
    println(SI) # prints 3
    
    还要注意代码中的输入错误
    get_prop
    需要检查
    mg
    ,而不是
    g
    。您还应该看看文档中的部分

    对于问题的第二部分,您应该为我们提供宏观定义,以便更好地帮助您。很可能,您不是宏中的表达式/变量。看一个不同的问题,并告诉如果这有帮助

    编辑1。实际上,你的第二部分也有同样的问题。在
    sum
    中,用分号结束位置参数,并启动

    编辑2。根据DNF下面的评论,您甚至应该使用
    count
    来获得更具表现力(源代码)和效率的版本:

    SI = count(e->(get_prop(mg, dst(e), :vessel) == 2 &&
                   get_prop(mg, dst(e), :port  ) == 1   ), edges(mg))
    # or,
    SI = count(get_prop(mg, dst(e), :vessel) == 2 &&
               get_prop(mg, dst(e), :port  ) == 1    for e in edges(mg))
    
    编辑3。性能比较如下:

    Pkg.add("BenchmarkTools")
    using BenchmarkTools
    
    @benchmark count(e->(get_prop(mg, dst(e), :vessel) == 2 &&
                         get_prop(mg, dst(e), :port  ) == 1   ), edges(mg))
    
    BenchmarkTools.Trial:
      memory estimate:  7.73 KiB
      allocs estimate:  53
      --------------
      minimum time:     2.201 μs (0.00% GC)
      median time:      2.494 μs (0.00% GC)
      mean time:        3.191 μs (15.69% GC)
      maximum time:     198.515 μs (95.69% GC)
      --------------
      samples:          10000
      evals/sample:     9
    
    @benchmark count(get_prop(mg, dst(e), :vessel) == 2 &&
                     get_prop(mg, dst(e), :port  ) == 1    for e in edges(mg))
    
    BenchmarkTools.Trial:
      memory estimate:  7.75 KiB
      allocs estimate:  54
      --------------
      minimum time:     2.352 μs (0.00% GC)
      median time:      2.661 μs (0.00% GC)
      mean time:        3.712 μs (15.10% GC)
      maximum time:     236.440 μs (95.06% GC)
      --------------
      samples:          10000
      evals/sample:     9
    
    @benchmark length([e for e in edges(mg) if get_prop(mg, dst(e), :vessel) == 2 &&
                                               get_prop(mg, dst(e), :port  ) == 1])
    
    BenchmarkTools.Trial:
      memory estimate:  8.13 KiB
      allocs estimate:  60
      --------------
      minimum time:     2.642 μs (0.00% GC)
      median time:      2.789 μs (0.00% GC)
      mean time:        3.553 μs (14.54% GC)
      maximum time:     231.424 μs (94.73% GC)
      --------------
      samples:          10000
      evals/sample:     9
    
    count
    版本的效率似乎比
    length
    高10%,这可能会对您的实际更大问题产生影响

    编辑4。由于DNF,进行基准测试的正确方法如下:

    @benchmark count(e->(get_prop($mg, dst(e), :vessel) == 2 &&
                         get_prop($mg, dst(e), :port  ) == 1   ), edges($mg))
    
    BenchmarkTools.Trial:
      memory estimate:  7.72 KiB
      allocs estimate:  52
      --------------
      minimum time:     2.320 μs (0.00% GC)
      median time:      2.478 μs (0.00% GC)
      mean time:        2.952 μs (10.33% GC)
      maximum time:     117.306 μs (93.38% GC)
      --------------
      samples:          10000
      evals/sample:     9
    
    @benchmark count(get_prop($mg, dst(e), :vessel) == 2 &&
                     get_prop($mg, dst(e), :port  ) == 1    for e in edges($mg))
    
    BenchmarkTools.Trial:
      memory estimate:  7.73 KiB
      allocs estimate:  53
      --------------
      minimum time:     2.340 μs (0.00% GC)
      median time:      2.524 μs (0.00% GC)
      mean time:        3.030 μs (11.17% GC)
      maximum time:     197.018 μs (94.35% GC)
      --------------
      samples:          10000
      evals/sample:     9
    

    在这里使用
    count
    更有效、更简洁,无需分配数组。使用
    count(pred(n)代替
    length([n代表n in coll,如果pred(n)])
    ,使用
    count(pred(n)代表n in coll)
    count(pred,coll)
    ,其中
    pred
    是您的谓词函数。实际上,您应该使用
    @benchmark
    :如
    @benchmark count(pred,$coll)
    count
    实现的分配应该为零,并且可能会有更大的加速。@DNF,我再次更新了它。插值似乎没有任何改进。我在
    0.6.2
    上。也许你应该运行这个程序,用正确的方法来做,并相应地编辑我的答案。但一般来说,在基准代码中插入变量是一种很好的做法,如果你不这样做,当编译器无法推断变量类型时,你经常会得到显著的减速。而且,您可能需要考虑<代码>文件过滤边缘>代码>,而不是在理解中的每个边上调用<代码> GETYPROSP:<代码> FieldILL边(mg,(g,e)-gETyPROP(g,e,:容器)=2 & & ggpOpP(g,e,:端口)=1)< /代码>。这里更有效和简洁地使用<代码>计数< /代码>,不需要分配数组。使用
    count(pred(n)代替
    length([n代表n in coll,如果pred(n)])
    ,使用
    count(pred(n)代表n in coll)
    count(pred,coll)
    ,其中
    pred
    是您的谓词函数。实际上,您应该使用
    @benchmark
    :如
    @benchmark count(pred,$coll)
    count
    实现的分配应该为零,并且可能会有更大的加速。@DNF,我再次更新了它。插值似乎没有任何改进。我在
    0.6.2
    上。也许你应该运行这个程序,用正确的方法来做,并相应地编辑我的答案。但一般来说,在基准代码中插入变量是一种很好的做法,如果你不这样做,当编译器无法推断变量类型时,你经常会得到显著的减速。而且,你可能想考虑<代码>文件过滤边缘<代码>,而不是在理解中的每一个边上调用<代码> GETYPROSP:<代码> FieldIn边(mg,(g,e)-gETy-PROP(g,e,:容器)=2 & & ggpOpP(g,e,:端口)=1)< /COD>。