替换“评估”;有更好的解决方案
这个方法确实有效,但是效果非常慢。我认为问题之一可能是 add_by 方法中的“eval”语句。
一些解释:每个 Node 对象都有三个相关属性,:x
、:y
和 :neighbors
。 :x
和 :y
是代表平面坐标的整数,:neighbors
是一个数组,节点存储在 @nodes< /代码> 数组。目标是为
一定距离内的节点code> 并将它们添加到 @nodes
中的每个节点 k
找到距 k
dk
的 @neighbors
数组中。
def set_neighbors d
def add_by dim, d
dict = {}
@nodes.each{|k| dict[k] = []}
@nodes.each_index do |k|
up = k+1
down = k-1
while up < @nodes.length and ((eval '@nodes[k].'+ dim) - (eval '@nodes[up].'+dim)).abs <= d
dict[@nodes[k]].push(@nodes[up])
up += 1
end
while down >= 0 and ((eval '@nodes[k].'+ dim) - (eval '@nodes[down].'+dim)).abs <= d
dict[@nodes[k]].push(@nodes[down])
down -= 1
end
end
return dict
end
@nodes.sort_by{|k| k.x}
exis = add_by('x', d)
whys = add_by('y', d)
@nodes.each do |k|
neighbors = exis[k]&whys[k]
k.neighbors = neighbors.select{|j| planar_distance(j,k) <= d}
end
end
我的问题是,如何在不重复 x
和 y
的 add_by
例程或使用 eval 的情况下执行此操作?
This method works, but it works very slowly. I think one of the problems might be the 'eval' statements in the add_by
method.
Some explanation: every Node object has three relevant attributes, :x
, :y
and :neighbors
. :x
and :y
are integers representing planar coordinates, :neighbors
is an array, and nodes are stored in the @nodes
array. The goal is to find, for each node k
in @nodes
, the nodes that are within some distance d
of k
and add them to the @neighbors
array of k
.
def set_neighbors d
def add_by dim, d
dict = {}
@nodes.each{|k| dict[k] = []}
@nodes.each_index do |k|
up = k+1
down = k-1
while up < @nodes.length and ((eval '@nodes[k].'+ dim) - (eval '@nodes[up].'+dim)).abs <= d
dict[@nodes[k]].push(@nodes[up])
up += 1
end
while down >= 0 and ((eval '@nodes[k].'+ dim) - (eval '@nodes[down].'+dim)).abs <= d
dict[@nodes[k]].push(@nodes[down])
down -= 1
end
end
return dict
end
@nodes.sort_by{|k| k.x}
exis = add_by('x', d)
whys = add_by('y', d)
@nodes.each do |k|
neighbors = exis[k]&whys[k]
k.neighbors = neighbors.select{|j| planar_distance(j,k) <= d}
end
end
My question is, how would you do this without either repeating the add_by
routine for x
and y
or using eval?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用
@nodes[k].send dim.to_sym
来避免 eval。我不确定你的代码到底在做什么,但也许有一些提示:
You can avoid eval by using
@nodes[k].send dim.to_sym
.I'm not sure what your code is doing exactly, but maybe a few pointers:
我会怎样做呢?我将通过 neo4j gem 使用 Neo4J 图形数据库 (来源)。如果您担心性能,这针对图形距离计算进行了优化。 API 也非常好。
话虽这么说,你真的根本不需要 eval。您可以使用
send
在对象上调用计算方法名称。所以你可以用@nodes[k].send(dim)
、@nodes[up].send(dim)
等替换上面的内容。How would I do it? I'd use the Neo4J graph database via the neo4j gem (source). If you're concerned about performance, this is optimized for graph distance calculations. Also the API is very nice.
That being said, you really don't need eval at all. You can call a calculated method name on an object by using
send
. So you can replace the above with@nodes[k].send(dim)
,@nodes[up].send(dim)
, etc.