Ruby false的未定义方法“[]”:FalseClass(NoMethodError)

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

我是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

   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 ], ...]