Cette méthode fonctionne, mais elle fonctionne très lentement. Je pense que l'un des problèmes pourrait être les déclarations 'eval' dans la méthode add_by
.en remplaçant 'eval' par une meilleure solution
Quelques explications: chaque objet Node a trois attributs pertinents, :x
, :y
et :neighbors
. :x
et :y
sont des entiers représentant des coordonnées planaires, :neighbors
est un tableau et les noeuds sont stockés dans le tableau @nodes
. Le but est de trouver, pour chaque nœud k
dans @nodes
, les nœuds qui se trouvent à une certaine distance d
de k
et de les ajouter au tableau @neighbors
de 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
Ma question est, comment voulez-vous faire sans soit répéter la routine add_by
pour x
et y
ou en utilisant eval?
Cela a accéléré les choses un peu, merci! – philosodad
Je devrais mentionner, cependant, que la raison de ne pas utiliser .select ici est parce que le nombre de noeuds est très, très grand, et les nombres qui sont dans la distance planaire sont petits. Donc, compter à partir de l'index après le tri a du sens ... il devrait y avoir un tri par là aussi. – philosodad
Le code que vous avez fourni ne fait pas le tri. 'sort_by' ne fait pas de tri en place mais retourne plutôt un tableau trié. –