lnd.xprv/routing/rt/graph/dijkstra.go
BitfuryLightning 327768f4ad routing: Move tools inside lnd. Refactor and delete unneeded stuff
Use [33]byte for graph vertex representation.
Delete unneeded stuff:
1. DeepEqual for graph comparison
2. EdgePath
3. 2-thread BFS
4. Table transfer messages and neighborhood radius
5. Beacons

Refactor:
1. Change ID to Vertex
2. Test use table driven approach
3. Add comments
4. Make graph internal representation private
5. Use wire.OutPoint as  EdgeId
6. Decouple routing messages from routing implementation
7. Delete Async methods
8. Delete unneeded channels and priority buffer from manager
9. Delete unneeded interfaces in internal graph realisation
10. Renamed ID to Vertex
2016-11-23 20:37:43 -06:00

68 lines
1.5 KiB
Go

// 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 "math"
func DijkstraPathWeight(g *Graph, source, target Vertex) (float64, error) {
dist, _, err := dijkstra(g, source, target)
if err != nil {
return 0, err
}
if _, ok := dist[target]; !ok {
return 0, PathNotFoundError
}
return dist[target], nil
}
func DijkstraPath(g *Graph, source, target Vertex) ([]Vertex, error) {
_, parent, err := dijkstra(g, source, target)
if err != nil {
return nil, err
}
if _, ok := parent[target]; !ok {
return nil, PathNotFoundError
}
path, err := Path(source, target, parent)
if err != nil {
return nil, err
}
return path, nil
}
func dijkstra(g *Graph, source, target Vertex) (map[Vertex]float64, map[Vertex]Vertex, error) {
dist := make(map[Vertex]float64)
colored := make(map[Vertex]bool)
parent := make(map[Vertex]Vertex)
dist[source] = 0
for {
bestDist := math.MaxFloat64
var bestID Vertex
for id, val := range dist {
if val < bestDist && !colored[id] {
bestDist = val
bestID = id
}
}
if bestID == target {
break
}
colored[bestID] = true
targets, err := g.GetNeighbors(bestID)
if err != nil {
return nil, nil, err
}
for id, multiedges := range targets {
for _, edge := range multiedges {
if have, ok := dist[id]; !ok || have > dist[bestID]+edge.Wgt {
dist[id] = dist[bestID] + edge.Wgt
parent[id] = bestID
}
}
}
}
return dist, parent, nil
}