-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgraph.go
More file actions
138 lines (119 loc) · 3.07 KB
/
Copy pathgraph.go
File metadata and controls
138 lines (119 loc) · 3.07 KB
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
package main
import (
"bytes"
"fmt"
)
// A Vertex represents a node in a directed multi graph.
type Vertex struct {
id string
In map[string]*Arc // map of ingoing arcs
Out map[string]*Arc // map of outgoing arcs
}
func NewVertex(id string) *Vertex {
v := &Vertex{id: id,
In: make(map[string]*Arc),
Out: make(map[string]*Arc),
}
return v
}
func (v *Vertex) AddIngoingArc(arc *Arc) error {
if _, ok := v.In[arc.from]; !ok {
v.In[arc.from] = arc
} else {
return fmt.Errorf("arc <%s --> %s> already exist in vertex <%s> ", arc.from, arc.to, v.id)
}
return nil
}
func (v *Vertex) AddOutgoingArc(arc *Arc) error {
if _, ok := v.Out[arc.to]; !ok {
v.Out[arc.to] = arc
} else {
return fmt.Errorf("arc <%s --> %s> already exist in vertex <%s> ", arc.from, arc.to, v.id)
}
return nil
}
func (v *Vertex) GetIngoingArc(from string) (*Arc, bool) {
arc, ok := v.In[from]
return arc, ok
}
func (v *Vertex) GetOutgoingArc(to string) (*Arc, bool) {
arc, ok := v.Out[to]
return arc, ok
}
// An Arc represents a parallel edges in the directed multi graph.
type Arc struct {
from string
to string
edges map[string]*Edge
}
func NewArc(from, to string) *Arc {
a := &Arc{from: from,
to: to,
edges: make(map[string]*Edge)}
return a
}
func (a *Arc) AddEdge(edge *Edge) error {
if _, ok := a.edges[edge.id]; !ok {
a.edges[edge.id] = edge
} else {
return fmt.Errorf("edge <%s> already exist in arc <%s --> %s> ", edge.id, a.from, a.to)
}
return nil
}
func (a *Arc) GetEdges() map[string]*Edge {
return a.edges
}
// An Edge represents a single connection between two vertices
// an Arc contains from one or more edges
type Edge struct {
id string
data interface{}
}
func NewEdge(id string, data interface{}) *Edge {
return &Edge{id: id, data: data}
}
// Graph describes the methods of graph operations.
// It assumes that the identifier of a Vertex is unique.
type Graph struct {
Vertices map[string]*Vertex //Map of vertices by their id
}
func NewGraph() *Graph {
g := &Graph{Vertices: make(map[string]*Vertex)}
return g
}
// AddVertex adds new vertex, return an error if vertex with same id already exist
func (g *Graph) AddVertex(v *Vertex) error {
if _, ok := g.GetVertex(v.id); !ok {
g.Vertices[v.id] = v
} else {
return fmt.Errorf("vertex <%s> is already exist", v.id)
}
return nil
}
// GetVertex return a vertex and true if its present in graph
// nil and false otherwise
func (g *Graph) GetVertex(id string) (*Vertex, bool) {
v, ok := g.Vertices[id]
return v, ok
}
// returns all vertices
func (g *Graph) GetVertices() map[string]*Vertex {
return g.Vertices
}
// converts all graph data into string
func (g *Graph) String() string {
buf := new(bytes.Buffer)
// iterate over all vertices of graph
for _, node := range g.Vertices {
fmt.Fprintf(buf, "%s\n", node.id)
// iterate over all arcs out from vertex
for _, arc := range node.Out {
fmt.Fprintf(buf, "%s --- > %s\n", arc.from, arc.to)
// iterate over all edges of arc
for _, edge := range arc.edges {
fmt.Fprintf(buf, "%s ---- %v\n", edge.id, edge.data)
}
}
}
return buf.String()
}