pull/158/merge
ali pourghasemi 5 months ago committed by GitHub
commit f87e652c6b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,119 @@
package graphs
// Graph holds vertices and edges of a graph
type Graph struct {
isDirected bool
vertices []node
}
type node struct {
name interface{}
edges []interface{}
}
const infinity = int(^uint(0) >> 1)
// NewDirectedGraph is for creating a directed graph
func NewDirectedGraph() *Graph {
g := Graph{}
g.vertices = make([]node, 0)
g.isDirected = true
return &g
}
// NewUndirectedGraph is for creating an undirected graph
func NewUndirectedGraph() *Graph {
g := Graph{}
g.vertices = make([]node, 0)
g.isDirected = false
return &g
}
// AddVertice is for adding a new vertice. id vertice exists do nothing
func (g *Graph) AddVertice(name interface{}) {
g.addVertice(name)
}
// AddEdge if for adding a new edge.
func (g *Graph) AddEdge(from, to interface{}) {
g.addEdge(from, to)
}
// GetEdge is for getting all the edges of vertice n
func (g *Graph) GetEdge(n interface{}) []interface{} {
return g.getEdge(n)
}
// GetVertices is for getting all vertices info
func (g *Graph) GetVertices() []interface{} {
return g.getVertices()
}
// ShortestPath is for finding shortest path from edge s to t by using belman-ford algorithm
func (g *Graph) ShortestPath(s, t interface{}) map[interface{}]int {
return g.shortestPath(s, t)
}
func (g *Graph) addVertice(name interface{}) int {
for i, v := range g.vertices {
if v.name == name {
return i
}
}
n := node{}
n.name = name
n.edges = make([]interface{}, 0)
g.vertices = append(g.vertices, n)
return len(g.vertices) - 1
}
func (g *Graph) addEdge(from, to interface{}) {
f := g.addVertice(from)
t := g.addVertice(to)
g.vertices[f].edges = append(g.vertices[f].edges, to)
if !g.isDirected {
g.vertices[t].edges = append(g.vertices[t].edges, from)
}
}
func (g *Graph) getEdge(n interface{}) []interface{} {
for _, v := range g.vertices {
if v.name == n {
return v.edges
}
}
// todo throw exception
return nil
}
func (g *Graph) getVertices() []interface{} {
vertices := make([]interface{}, 0)
for i := 0; i < len(g.vertices); i++ {
vertices = append(vertices, g.vertices[i].name)
}
return vertices
}
func (g *Graph) shortestPath(sName, tName interface{}) map[interface{}]int {
n := len(g.vertices)
s := g.addVertice(sName)
dist := make([]int, n)
for i := 0; i < n; i++ {
dist[i] = infinity
}
dist[s] = 0
for u := 0; u < n-1; u++ {
for _, vName := range g.vertices[u].edges {
v := g.addVertice(vName)
if dist[u] != infinity && dist[u]+1 < dist[v] {
dist[v] = dist[u] + 1
}
}
}
result := make(map[interface{}]int)
for i, d := range dist {
result[g.vertices[i].name] = d
}
return result
}

@ -0,0 +1,102 @@
package graphs
import (
"testing"
)
func TestGrsphAddVertice(t *testing.T) {
g1 := NewDirectedGraph()
g1.AddVertice("a")
g1.AddVertice("b")
g1.AddVertice("c")
g1.AddVertice("d")
actualValue1 := g1.GetVertices()
expectedValue1 := []string{"a", "b", "c", "d"}
for i, v := range expectedValue1 {
if v != actualValue1[i] {
t.Errorf("Got %v expected %v", actualValue1, expectedValue1)
return
}
}
g2 := NewDirectedGraph()
g2.AddVertice(1)
g2.AddVertice(2)
g2.AddVertice(3)
g2.AddVertice(4)
actualValue2 := g2.GetVertices()
expectedValue2 := []int{1, 2, 3, 4}
for i, v := range expectedValue2 {
if v != actualValue2[i] {
t.Errorf("Got %v expected %v", actualValue2, expectedValue2)
return
}
}
g3 := NewUndirectedGraph()
g3.AddVertice("a")
g3.AddVertice("b")
g3.AddVertice("c")
g3.AddVertice("d")
actualValue3 := g3.GetVertices()
expectedValue3 := []string{"a", "b", "c", "d"}
for i, v := range expectedValue3 {
if v != actualValue3[i] {
t.Errorf("Got %v expected %v", actualValue3, expectedValue3)
return
}
}
}
func TestGrsphAddEdge(t *testing.T) {
g1 := NewDirectedGraph()
g1.AddVertice("a")
g1.AddVertice("b")
g1.AddEdge("a", "b")
g1.AddEdge("c", "a")
actualValue1 := g1.GetEdge("a")
expectedValue1 := []string{"b"}
for i, v := range expectedValue1 {
if v != actualValue1[i] {
t.Errorf("Got %v expected %v", actualValue1, expectedValue1)
return
}
}
g2 := NewUndirectedGraph()
g2.AddVertice("a")
g2.AddVertice("b")
g2.AddEdge("a", "b")
g2.AddEdge("c", "a")
actualValue2 := g2.GetEdge("a")
expectedValue2 := []string{"b", "c"}
for i, v := range expectedValue2 {
if v != actualValue2[i] {
t.Errorf("Got %v expected %v", actualValue2, expectedValue2)
return
}
}
}
func TestShortestPath(t *testing.T) {
g := NewDirectedGraph()
g.addEdge("a", "b")
g.addEdge("b", "c")
g.addEdge("c", "a")
g.addEdge("c", "d")
tests := [][]interface{}{
{1, "a", 0},
{2, "b", 1},
{3, "c", 2},
{4, "d", 3},
}
for _, test := range tests {
actualValue, expectedValue := g.shortestPath("a", "b")[test[1]], test[2]
if actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
}
Loading…
Cancel
Save