lnd.xprv/routing/rt/graph/bfs.go

68 lines
1.5 KiB
Go
Raw Normal View History

// Copyright (c) 2016 Bitfury Group Limited
// Distributed under the MIT software license, see the accompanying
// file LICENSE or http://www.opensource.org/licenses/mit-license.php
package graph
import "container/list"
func ShortestPathLen(g *Graph, v1, v2 Vertex) (int, error) {
dist, _, err := bfs(g, v1, v2)
if err != nil {
return 0, err
}
if _, ok := dist[v2]; !ok {
return 0, PathNotFoundError
}
return dist[v2], nil
}
func ShortestPath(g *Graph, v1, v2 Vertex) ([]Vertex, error) {
_, parent, err := bfs(g, v1, v2)
if err != nil {
return nil, err
}
if _, ok := parent[v2]; !ok {
return nil, PathNotFoundError
}
path, err := Path(v1, v2, parent)
if err != nil {
return nil, err
}
return path, nil
}
func bfs(g *Graph, v1, v2 Vertex) (map[Vertex]int, map[Vertex]Vertex, error) {
var queue list.List
queue.PushBack(v1)
dist := make(map[Vertex]int)
parent := make(map[Vertex]Vertex)
dist[v1] = 0
for queue.Len() != 0 {
err := ibfs(g, queue.Front().Value.(Vertex), &queue, dist, parent)
if err != nil {
return nil, nil, err
}
if _, ok := dist[v2]; ok {
break
}
}
return dist, parent, nil
}
func ibfs(g *Graph, v Vertex, queue *list.List, dist map[Vertex]int, parent map[Vertex]Vertex) error {
queue.Remove(queue.Front())
targets, err := g.GetNeighbors(v)
if err != nil {
return err
}
for to := range targets {
if _, ok := dist[to]; !ok {
dist[to] = dist[v] + 1
parent[to] = v
queue.PushBack(to)
}
}
return nil
}