我是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
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>'
答案 0 :(得分:1)
代码很难理解,但直觉告诉我问题是关于线的
dist[i]=999,sptSet=false
因为在定义sptSet之前有3行
sptSet=Array.new(9)
所以首先你要制作数组,然后你将它改为false。你想要达到的目标可能是:
dist[i]=999,sptSet[i]=false
答案 1 :(得分:1)
您将false
分配给sptSet
dist[i]=999,sptSet=false
将其传递给minDistance
,并且在此方法体中,您希望sptSet为Array
if sptSet[v]==false && dist[v]<=999
答案 2 :(得分:0)
我的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
您必须以
格式传递边缘[['vertex_1', 'vertex_2', weight], ['vertex_2', 'vertex_3', weight ], ...]