-
Notifications
You must be signed in to change notification settings - Fork 1
/
weightgraph.go
153 lines (128 loc) · 3.15 KB
/
weightgraph.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package graph
import (
"bytes"
"fmt"
"io"
)
// WeightGraph is a graph with weighted edges.
type WeightGraph struct {
adj [][]Edge
e int
}
// NewWeightGraph creates an empty graph with v vertices
func NewWeightGraph(v int) WeightGraph {
return WeightGraph{
adj: make([][]Edge, v),
e: 0,
}
}
// ReadWeightGraph constructs an undirected graph from the io.Reader expecting
// to find data formed such as:
// v
// e
// a b w0
// c d w1
// ...
// y z wN
// where `v` is the vertex count, `e` the number of edges and `a`, `b`, `c`,
// `d`, ..., `y` and `z` are edges between `a` and `b`, `c` and `d`, ..., and
// `y` and `z` respectively, and `wN` is the weight of that edge.
func ReadWeightGraph(input io.Reader) (WeightGraph, error) {
scan := newWeighGraphScanner(input)
v, err := scan.NextInt()
if err != nil {
return WeightGraph{}, fmt.Errorf("failed reading vertex count, %v", err)
}
g := NewWeightGraph(v)
e, err := scan.NextInt()
if err != nil {
return WeightGraph{}, fmt.Errorf("failed reading edge count, %v", err)
}
for i := 0; i < e; i++ {
from, to, weight, err := scan.NextEdge()
if err != nil {
return g, fmt.Errorf("failed at edge line=%d, %v", i, err)
}
g.AddEdge(NewEdge(from, to, weight))
}
return g, nil
}
// AddEdge adds weigthed edge e to this graph
func (wg *WeightGraph) AddEdge(e Edge) {
wg.adj[e.from] = append(wg.adj[e.from], e)
wg.adj[e.to] = append(wg.adj[e.to], e)
wg.e++
}
// Adj gives the edges incident to v
func (wg *WeightGraph) Adj(v int) []Edge {
return wg.adj[v]
}
// Edges gives all the edges in this graph
func (wg *WeightGraph) Edges() []Edge {
var edges []Edge
for v := 0; v < wg.V(); v++ {
for _, adj := range wg.Adj(v) {
if adj.Other(v) > v {
edges = append(edges, adj)
}
}
}
return edges
}
// V is the number of vertives
func (wg *WeightGraph) V() int {
return len(wg.adj)
}
// E is the number of edges
func (wg *WeightGraph) E() int {
return wg.e
}
// GoString represents this weighted graph
func (wg *WeightGraph) GoString() string {
var output bytes.Buffer
do := func(n int, err error) {
if err != nil {
panic(err)
}
}
for v := 0; v < wg.V(); v++ {
for _, w := range wg.Adj(v) {
do(output.WriteString(w.GoString()))
do(output.WriteRune('\n'))
}
}
return output.String()
}
// Edge is a weighted edge in a weighted graph
type Edge struct {
weight float64
from int
to int
}
// NewEdge creates a weigthed edge to be used by a WeightGraph
func NewEdge(v, w int, weight float64) Edge {
return Edge{weight: weight, from: v, to: w}
}
// Less tells if this edge is less than the other edge
func (e *Edge) Less(other Edge) bool {
return e.weight < other.weight
}
// Either returns either vertices of this edge.
func (e *Edge) Either() int {
return e.from
}
// Other tells the other end of this edge, from v's perspective.
func (e *Edge) Other(v int) int {
if e.from == v {
return e.to
}
return e.from
}
// Weight tells the weight of this edge
func (e *Edge) Weight() float64 {
return e.weight
}
// GoString represents this edge in a directed, weighted fashion
func (e *Edge) GoString() string {
return fmt.Sprintf("%d-%d %.5f", e.from, e.to, e.weight)
}