Skip to content

Commit 2871600

Browse files
committed
chore: change example to document Set method usage.
Add example demonstrating usage of the Set method with Djikstra algorithm for finding shortest path in a graph.
1 parent eaf390e commit 2871600

File tree

1 file changed

+80
-21
lines changed

1 file changed

+80
-21
lines changed

kpq/example_test.go

Lines changed: 80 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ import (
44
"errors"
55
"fmt"
66
"log"
7+
"math"
8+
"os"
9+
"text/tabwriter"
710

811
"github.com/rdleal/go-priorityq/kpq"
912
)
@@ -64,35 +67,91 @@ func Example() {
6467
}
6568

6669
func ExampleKeyedPriorityQueue_Set() {
67-
cmp := func(a, b int) bool {
68-
return a < b
70+
// This code implements Dijkstra's algorithm to find the shortest path in a
71+
// weighted graph from a source vertex to all other vertices.
72+
//
73+
// This example shows how to change the priority in `KeyedPriorityQueue`
74+
// when needed.
75+
graph := struct {
76+
len int
77+
edges []int
78+
}{
79+
len: 8,
80+
// edges represents the adjacency matrix of a directed weighted Graph.
81+
edges: []int{
82+
0, 5, 0, 0, 9, 0, 0, 8,
83+
0, 0, 12, 15, 0, 0, 0, 4,
84+
0, 0, 0, 3, 0, 0, 11, 0,
85+
0, 0, 0, 0, 0, 0, 9, 0,
86+
0, 0, 0, 0, 0, 4, 20, 5,
87+
0, 0, 1, 0, 0, 0, 13, 0,
88+
0, 0, 0, 0, 0, 0, 0, 0,
89+
0, 0, 7, 0, 0, 6, 0, 0,
90+
},
6991
}
70-
pq := kpq.NewKeyedPriorityQueue[string](cmp)
7192

72-
// Insert elements onto the priority queue
73-
pq.Push("second", 42)
74-
pq.Push("first", 30)
75-
pq.Push("last", 50)
93+
edge := func(u, v int) (weight int) {
94+
return graph.edges[graph.len*u+v]
95+
}
7696

77-
// Updates an element
78-
pq.Set("last", 20)
97+
adj := func(v int) []int {
98+
vertices := make([]int, 0)
7999

80-
k, v, ok := pq.Pop()
81-
if !ok {
82-
log.Fatal("priority queue is empty")
100+
for i := 0; i < graph.len; i++ {
101+
if weight := edge(v, i); weight > 0 {
102+
vertices = append(vertices, i)
103+
}
104+
}
105+
106+
return vertices
83107
}
84108

85-
fmt.Printf("Key: %q, Value: %d\n", k, v)
109+
src := 0
86110

87-
// Inserts a new element
88-
pq.Set("new_first", 1)
89-
k, v, ok = pq.Pop()
90-
if !ok {
91-
log.Fatal("priority queue is empty")
111+
distTo := make([]int, graph.len)
112+
for i := 0; i < graph.len; i++ {
113+
distTo[i] = math.MaxInt
114+
}
115+
distTo[src] = 0
116+
117+
// cmpFunc maintains the variant of a min priority queue,
118+
// needed for relaxing all the edges from the source.
119+
cmpFunc := func(a, b int) bool {
120+
return a < b
121+
}
122+
pq := kpq.NewKeyedPriorityQueue[int](cmpFunc)
123+
pq.Push(src, 0) // starts with source vertex.
124+
125+
for !pq.IsEmpty() {
126+
u, dist, _ := pq.Pop()
127+
// Iterate over vertices adjacent to vertex u, and relax each edge
128+
// between them.
129+
// Given a vertex u and v and a weighted edge e from u to v,
130+
// the relaxation algorithm updates the value in the priority queue
131+
// if the edge e provides a shorter path from u to v than previously known.
132+
for _, v := range adj(u) {
133+
weight := edge(u, v)
134+
if distTo[v] > dist+weight {
135+
distTo[v] = dist + weight
136+
pq.Set(v, distTo[v])
137+
}
138+
}
92139
}
93140

94-
fmt.Printf("Key: %q, Value: %d\n", k, v)
141+
w := tabwriter.NewWriter(os.Stdout, 0, 0, 4, ' ', 0)
142+
fmt.Fprintln(w, "Vertex\tDistance From Source")
143+
for i := 0; i < graph.len; i++ {
144+
fmt.Fprintf(w, "%3d\t%10d\n", i, distTo[i])
145+
}
146+
w.Flush()
95147
// Output:
96-
// Key: "last", Value: 20
97-
// Key: "new_first", Value: 1
148+
// Vertex Distance From Source
149+
// 0 0
150+
// 1 5
151+
// 2 14
152+
// 3 17
153+
// 4 9
154+
// 5 13
155+
// 6 25
156+
// 7 8
98157
}

0 commit comments

Comments
 (0)