Ruby false的未定义方法“[]”:FalseClass(NoMethodError)
我是ruby的初学者,这里附上我的错误代码,请帮助我解决ruby中Dijkstra算法实现中的错误Ruby false的未定义方法“[]”:FalseClass(NoMethodError),ruby,dijkstra,Ruby,Dijkstra,我是ruby的初学者,这里附上我的错误代码,请帮助我解决ruby中Dijkstra算法实现中的错误 #!/usr/bin/env ruby def minDistance(dist,sptSet) min=999,min_index=0,v=0 for v in 0...9 if sptSet[v]==false && dist[v]<=999 min=dist[v],min_index=v end end return min_index end
#!/usr/bin/env ruby
def minDistance(dist,sptSet)
min=999,min_index=0,v=0
for v in 0...9
if sptSet[v]==false && dist[v]<=999
min=dist[v],min_index=v
end
end
return min_index
end
def printSolution(dist,n)
puts "Vertex Distance from Source"
for i in 0...9
puts "#{i} #{dist[i]}"
end
end
def dijkstra(graph,src)
dist=Array.new(9)
sptSet=Array.new(9)
for i in 0...9
dist[i]=999,sptSet=false
end
dist[src]=0
for count in 0...8
u=minDistance(dist,sptSet)
sptSet[u]=true
for v in 0...9
if sptSet[v]==false && graph[u][v] && dist[u]!=999 && dist[u]+graph[u] [v]<dist[v]
dist[v]=dist[u]+graph[u][v]
end
end
end
printSolution(dist,9)
end
def main
graph=[[0,4,0,0,0,0,0,8,0],[4,0,8,0,0,0,0,11,0],[0,8,0,7,0,4,0,0,2],[0,0,7,0,9,14,0,0,0],[0,0,0,9,0,10,0,2,0,0],[0,0,0,14,0,2,0,1,6],[8,11,0,0,0,0,1,0,7],[0,0,2,0,0,0,6,7,0]]
dijkstra(graph,0)
end
main
下面是显示给我的错误。请帮我找到我在哪里犯的错误,并给出正确的解释
in `block in minDistance': undefined method `[]' for false:FalseClass (NoMethodError)
from rubyfirst.rb:5:in `each'
from rubyfirst.rb:5:in `minDistance'
from rubyfirst.rb:29:in `block in dijkstra'
from rubyfirst.rb:28:in `each'
from rubyfirst.rb:28:in `dijkstra'
from rubyfirst.rb:46:in `main'
from rubyfirst.rb:50:in `<main>'
代码很难理解,但直觉告诉我问题出在线条上 dist[i]=999,sptSet=false 因为在定义sptSet之前有3行 sptSet=Array.new9 所以,首先要创建数组,然后将其更改为false。您想要实现的可能是: dist[i]=999,sptSet[i]=false您将false指定给sptSet 将它传递给MindDistance,在这个方法体中,您希望sptSet是一个数组
我的Dijkstra实现示例:
class Dijkstra
attr_accessor :graph, :origin, :destination, :edges, :verticies
def initialize(origin, destination, edges)
self.graph = []
self.edges = edges
self.verticies = unique_verticies
populate_graph(origin, destination)
end
def populate_graph(origin, destination)
self.origin = origin
self.destination = destination
self.graph = create_nodes
populate_neighbors
recursive_dijkstra
end
def shortest_distance
self.graph.detect { |node| node[:vertex] == self.destination }[:distance]
end
def shortest_path
path = [self.destination]
predecessor = self.destination
while !predecessor.nil?
predecessor = self.graph.detect { |node| node[:vertex] == predecessor }[:predecessor]
path.unshift(predecessor) unless predecessor.nil?
end
path
end
private
def unique_verticies
self.edges.flatten.uniq.select { |edge| edge.class == String }
end
def create_nodes
self.verticies.map do |vertex|
node = { vertex: vertex, closed: false, predecessor: nil, distance: Float::INFINITY, neighbors: [] }
node[:distance] = 0 if vertex == origin
node
end
end
def populate_neighbors
self.verticies.each do |vertex|
self.edges.each do |edge|
if edge.include?(vertex)
self.graph.detect { |node| node[:vertex] == vertex }[:neighbors] << edge.detect { |neighbor| neighbor != vertex && neighbor.class == String }
end
end
end
end
def recursive_dijkstra
open_verticies = self.graph.select { |node| node[:closed] == false }.sort_by { |node| node[:distance] }
return if open_verticies.count == 0
node = open_verticies.first
node[:closed] = true
node[:neighbors].each do |neighbor|
neighbor_vertex = self.graph.detect { |node| node[:vertex] == neighbor && node[:closed] == false }
next if neighbor_vertex.nil?
self.edges.each do |edge|
if edge.include?(node[:vertex]) && edge.include?(neighbor_vertex[:vertex])
matcher_distance = node[:distance] + edge[2]
if matcher_distance < neighbor_vertex[:distance]
neighbor_vertex[:distance] = matcher_distance
neighbor_vertex[:predecessor] = node[:vertex]
end
end
end
end
recursive_dijkstra
end
end
谢谢…更正后,我得到了另一个错误:MindDistance中的block:undefined method change dist[i]=999,sptSet=false to dist[i]=999 sptSet=false`因此删除,并在9999后添加enter谢谢错误得到了解决,但出现了另一个错误:rubyfirst.rb:36:dijkstra中的block 2级别:undefined method[]'对于nil:NilClass nomethoder可能是因为您的图形数组只包含8个子数组,我想在做了所有更正后应该是9,我得到了这个结果:0 0 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0不要在变量或方法中使用CamelCase。
if sptSet[v]==false && dist[v]<=999
class Dijkstra
attr_accessor :graph, :origin, :destination, :edges, :verticies
def initialize(origin, destination, edges)
self.graph = []
self.edges = edges
self.verticies = unique_verticies
populate_graph(origin, destination)
end
def populate_graph(origin, destination)
self.origin = origin
self.destination = destination
self.graph = create_nodes
populate_neighbors
recursive_dijkstra
end
def shortest_distance
self.graph.detect { |node| node[:vertex] == self.destination }[:distance]
end
def shortest_path
path = [self.destination]
predecessor = self.destination
while !predecessor.nil?
predecessor = self.graph.detect { |node| node[:vertex] == predecessor }[:predecessor]
path.unshift(predecessor) unless predecessor.nil?
end
path
end
private
def unique_verticies
self.edges.flatten.uniq.select { |edge| edge.class == String }
end
def create_nodes
self.verticies.map do |vertex|
node = { vertex: vertex, closed: false, predecessor: nil, distance: Float::INFINITY, neighbors: [] }
node[:distance] = 0 if vertex == origin
node
end
end
def populate_neighbors
self.verticies.each do |vertex|
self.edges.each do |edge|
if edge.include?(vertex)
self.graph.detect { |node| node[:vertex] == vertex }[:neighbors] << edge.detect { |neighbor| neighbor != vertex && neighbor.class == String }
end
end
end
end
def recursive_dijkstra
open_verticies = self.graph.select { |node| node[:closed] == false }.sort_by { |node| node[:distance] }
return if open_verticies.count == 0
node = open_verticies.first
node[:closed] = true
node[:neighbors].each do |neighbor|
neighbor_vertex = self.graph.detect { |node| node[:vertex] == neighbor && node[:closed] == false }
next if neighbor_vertex.nil?
self.edges.each do |edge|
if edge.include?(node[:vertex]) && edge.include?(neighbor_vertex[:vertex])
matcher_distance = node[:distance] + edge[2]
if matcher_distance < neighbor_vertex[:distance]
neighbor_vertex[:distance] = matcher_distance
neighbor_vertex[:predecessor] = node[:vertex]
end
end
end
end
recursive_dijkstra
end
end
[['vertex_1', 'vertex_2', weight], ['vertex_2', 'vertex_3', weight ], ...]