I am implementing a function in ruby using BFS, and I would like to know how to print the shortest path in an undirected graph, between a start value and end value

**Graph**
In this example the graph has ten vertices. Each node represents a vertex and it has an array that stores adjacent nodes (edges).

```
$ irb
graph.to_s
1. 1 -> [2 3 4 5 8 9 10]
2. 2 -> [1 4 5 6 7 8 10]
3. 3 -> [1 4 6]
4. 4 -> [1 2 3 6 7 8 9 10]
5. 5 -> [1 2 8 9 10]
6. 6 -> [2 3 4 7 8 9 10]
7. 7 -> [2 4 6 8 9]
8. 8 -> [1 2 4 5 6 7 9 10]
9. 9 -> [1 4 5 6 7 8]
10. 10 -> [1 2 4 5 6 8]
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

```

**Expected Output**

2,1,9 or 2,4,9, etc.

**BFS**

```
def bfs_shortest_path(graph, start=2, search=9)
    if graph.nodes[start].nil? || graph.nodes[search].nil?
        return nil
    end
    visited = Set.new
    search_queue = Queue.new
    search_queue.enq(start)
    while !search_queue.empty? do      
        current_node_key = search_queue.deq  
        current_node = graph.nodes[current_node_key]         
        visited.add(current_node_key)
        if current_node.value == search
            return current_node # I would like to return the PATH Eg. 2,1,9
        end
        adjacent_nodes_array = current_node.adjacent_nodes.map{|x| x.value}
        adjacent_nodes_array.each do |value|
            if !visited.include?(value)                   
                search_queue.enq(value)
                graph.nodes[value].concat_to_path(current_node.path_from_start)                
            end
        end        
    end
end

```

Node

```
class Node
    attr_reader :value
    attr_reader :adjacent_nodes
    def initialize(value)
        @value = value
        @adjacent_nodes = []
    end

    def add_edge(node)
        @adjacent_nodes.push(node)
    end

    def to_s
        "#{@value} -> [#{@adjacent_nodes.map(&:value).sort.join(" ")}]"
    end
end

```

Graph

```
class Graph
    attr_reader :nodes    
    def initialize
        @nodes = {}
    end

    def add_node(node)        
        @nodes[node.value] = node
    end

    def add_edge(node1,node2)
        if @nodes[node1.value].adjacent_nodes.map(&:value).include? (node2.value)        
            puts "#{node1.value} and #{node2.value} already have an edge"
        elsif node1.value == node2.value
            puts "node1.value == node2.value"
        else
            @nodes[node1.value].add_edge(@nodes[node2.value])
            @nodes[node2.value].add_edge(@nodes[node1.value])
        end
    end

    def to_s
        @nodes.keys.sort.each_with_index do |key,index|
            puts "#{index + 1}. #{@nodes[key].to_s}" 
        end
    end
end

```

**Generating a Graph**

```
def generate_random_graph
    g = Graph.new
    [*1..10].shuffle.each do |node_value|
        g.add_node(Node.new(node_value))
    end
    40.times do 
        key1 = g.nodes.keys.sample
        key2 = g.nodes.keys.sample
        g.add_edge(g.nodes[key1],g.nodes[key2])
    end
    return g
end

```

**Test**

```
graph = generate_random_graph    
graph.to_s
bfs_shortest_path(graph,2,9)

```