Skip to content
This repository has been archived by the owner on Apr 26, 2019. It is now read-only.

Commit

Permalink
topo: add PathExistsIn helper function
Browse files Browse the repository at this point in the history
  • Loading branch information
kortschak committed Sep 29, 2016
1 parent 2fcd07f commit e9b5d80
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 0 deletions.
10 changes: 10 additions & 0 deletions topo/topo.go
Expand Up @@ -38,6 +38,16 @@ func IsPathIn(g graph.Graph, path []graph.Node) bool {
}
}

// PathExistsIn returns whether there is a path in g starting at from extending
// to to.
//
// PathExistsIn exists as a helper function. If many tests for path existence
// are being performed, other approaches will be more efficient.
func PathExistsIn(g graph.Graph, from, to graph.Node) bool {
var t traverse.BreadthFirst
return t.Walk(g, from, func(n graph.Node, _ int) bool { return n.ID() == to.ID() }) != nil
}

// ConnectedComponents returns the connected components of the undirected graph g.
func ConnectedComponents(g graph.Undirected) [][]graph.Node {
var (
Expand Down
75 changes: 75 additions & 0 deletions topo/topo_test.go
Expand Up @@ -54,6 +54,81 @@ func TestIsPath(t *testing.T) {
}
}

var pathExistsInUndirectedTests = []struct {
g []intset
from, to int
want bool
}{
{g: batageljZaversnikGraph, from: 0, to: 0, want: true},
{g: batageljZaversnikGraph, from: 0, to: 1, want: false},
{g: batageljZaversnikGraph, from: 1, to: 2, want: true},
{g: batageljZaversnikGraph, from: 2, to: 1, want: true},
{g: batageljZaversnikGraph, from: 2, to: 12, want: false},
{g: batageljZaversnikGraph, from: 20, to: 6, want: true},
}

func TestPathExistsInUndirected(t *testing.T) {
for i, test := range pathExistsInUndirectedTests {
g := simple.NewUndirectedGraph(0, math.Inf(1))

for u, e := range test.g {
if !g.Has(simple.Node(u)) {
g.AddNode(simple.Node(u))
}
for v := range e {
if !g.Has(simple.Node(v)) {
g.AddNode(simple.Node(v))
}
g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)})
}
}

got := PathExistsIn(g, simple.Node(test.from), simple.Node(test.to))
if got != test.want {
t.Errorf("unexpected result for path existance in test %d: got:%t want %t", i, got, test.want)
}
}
}

var pathExistsInDirectedTests = []struct {
g []intset
from, to int
want bool
}{
// The graph definition is such that from node IDs are
// less than to node IDs.
{g: batageljZaversnikGraph, from: 0, to: 0, want: true},
{g: batageljZaversnikGraph, from: 0, to: 1, want: false},
{g: batageljZaversnikGraph, from: 1, to: 2, want: true},
{g: batageljZaversnikGraph, from: 2, to: 1, want: false},
{g: batageljZaversnikGraph, from: 2, to: 12, want: false},
{g: batageljZaversnikGraph, from: 20, to: 6, want: false},
{g: batageljZaversnikGraph, from: 6, to: 20, want: true},
}

func TestPathExistsInDirected(t *testing.T) {
for i, test := range pathExistsInDirectedTests {
g := simple.NewDirectedGraph(0, math.Inf(1))

for u, e := range test.g {
if !g.Has(simple.Node(u)) {
g.AddNode(simple.Node(u))
}
for v := range e {
if !g.Has(simple.Node(v)) {
g.AddNode(simple.Node(v))
}
g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)})
}
}

got := PathExistsIn(g, simple.Node(test.from), simple.Node(test.to))
if got != test.want {
t.Errorf("unexpected result for path existance in test %d: got:%t want %t", i, got, test.want)
}
}
}

var connectedComponentTests = []struct {
g []intset
want [][]int
Expand Down

0 comments on commit e9b5d80

Please sign in to comment.