julia中边上的条件和
我有一个复杂的问题,我必须从先前构建的图中计算边上的和。 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
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>。