Exemplo n.º 1
0
func TestIntersectionDiff(t *testing.T) {
	s1 := set.NewSet()
	s2 := set.NewSet()
	s3 := set.NewSet()

	s1.Add(2)
	s1.Add(3)

	s2.Add(1)
	s2.Add(4)

	s3.Intersection(s1, s2)

	if card := s3.Cardinality(); card != 0 {
		t.Errorf("Intersection of different yields non-empty set %d", card)
	}

	if !s1.Contains(2) || !s1.Contains(3) || s1.Contains(1) || s1.Contains(4) || s1.Cardinality() != 2 {
		t.Error("Intersection of sets mutates non-destination set (argument 1)")
	}

	if s2.Contains(2) || s2.Contains(3) || !s2.Contains(1) || !s2.Contains(4) || s2.Cardinality() != 2 {
		t.Error("Intersection of sets mutates non-destination set (argument 1)")
	}
}
Exemplo n.º 2
0
func TestIntersectionOverlapping(t *testing.T) {
	s1 := set.NewSet()
	s2 := set.NewSet()
	s3 := set.NewSet()

	s1.Add(2)
	s1.Add(3)

	s2.Add(3)
	s2.Add(4)

	s3.Intersection(s1, s2)

	if card := s3.Cardinality(); card != 1 {
		t.Errorf("Intersection of overlapping sets yields set of incorrect cardinality %d", card)
	}

	if !s3.Contains(3) {
		t.Errorf("Intersection of overlapping sets yields set with wrong element")
	}

	if !s1.Contains(2) || !s1.Contains(3) || s1.Contains(4) || s1.Cardinality() != 2 {
		t.Error("Intersection of sets mutates non-destination set (argument 1)")
	}

	if s2.Contains(2) || !s2.Contains(3) || !s2.Contains(4) || s2.Cardinality() != 2 {
		t.Error("Intersection of sets mutates non-destination set (argument 1)")
	}
}
Exemplo n.º 3
0
func TestUnionOverlapping(t *testing.T) {
	s1 := set.NewSet()
	s2 := set.NewSet()
	s3 := set.NewSet()

	s1.Add(1)
	s1.Add(2)

	s2.Add(2)
	s2.Add(3)

	s3.Union(s1, s2)

	if s3.Cardinality() != 3 {
		t.Error("Union of overlapping sets yields set with wrong cardinality")
	}

	if !s3.Contains(1) || !s3.Contains(2) || !s3.Contains(3) {
		t.Error("Union of overlapping sets yields set with wrong elements")
	}

	if s1.Contains(3) || !s1.Contains(2) || !s1.Contains(1) || s1.Cardinality() != 2 {
		t.Error("Union of sets mutates non-destination set (argument 1)")
	}

	if !s2.Contains(3) || s2.Contains(1) || !s2.Contains(2) || s2.Cardinality() != 2 {
		t.Error("Union of sets mutates non-destination set (argument 2)")
	}
}
Exemplo n.º 4
0
func TestDiffSame(t *testing.T) {
	s1 := set.NewSet()
	s2 := set.NewSet()
	s3 := set.NewSet()

	s1.Add(1)
	s1.Add(2)

	s2.Add(1)
	s2.Add(2)

	s3.Diff(s1, s2)

	if card := s3.Cardinality(); card != 0 {
		t.Errorf("Difference of identical sets yields set with wrong cardinality %d", card)
	}

	if !s1.Contains(1) || !s1.Contains(2) || s1.Cardinality() != 2 {
		t.Error("Difference of identical sets mutates non-destination set (argument 1)")
	}

	if !s2.Contains(1) || !s2.Contains(2) || s2.Cardinality() != 2 {
		t.Error("Difference of identical sets mutates non-destination set (argument 1)")
	}
}
Exemplo n.º 5
0
func TestDiffOverlapping(t *testing.T) {
	s1 := set.NewSet()
	s2 := set.NewSet()
	s3 := set.NewSet()

	s1.Add(1)
	s1.Add(2)

	s2.Add(2)
	s2.Add(3)

	s3.Diff(s1, s2)

	if card := s3.Cardinality(); card != 1 {
		t.Errorf("Difference of overlapping sets yields set with wrong cardinality %d", card)
	}

	if !s3.Contains(1) || s3.Contains(2) || s3.Contains(3) {
		t.Error("Difference of overlapping sets yields set with wrong elements")
	}

	if !s1.Contains(1) || !s1.Contains(2) || s1.Contains(3) || s1.Cardinality() != 2 {
		t.Error("Difference of overlapping sets mutates non-destination set (argument 1)")
	}

	if s2.Contains(1) || !s2.Contains(2) || !s2.Contains(3) || s2.Cardinality() != 2 {
		t.Error("Difference of overlapping sets mutates non-destination set (argument 1)")
	}
}
Exemplo n.º 6
0
// Dijkstra's Algorithm is essentially a goalless Uniform Cost Search. That is, its results are roughly equivalent to
// running A* with the Null Heuristic from a single node to every other node in the graph -- though it's a fair bit faster
// because running A* in that way will recompute things it's already computed every call. Note that you won't necessarily get the same path
// you would get for A*, but the cost is guaranteed to be the same (that is, if multiple shortest paths exist, you may get a different shortest path).
//
// Like A*, Dijkstra's Algorithm likely won't run correctly with negative edge weights -- use Bellman-Ford for that instead
//
// Dijkstra's algorithm usually only returns a cost map, however, since the data is available this version will also reconstruct the path to every node
func Dijkstra(source Node, graph Graph, Cost func(Node, Node) float64) (paths map[int][]Node, costs map[int]float64) {
	if Cost == nil {
		if cgraph, ok := graph.(Coster); ok {
			Cost = cgraph.Cost
		} else {
			Cost = UniformCost
		}
	}
	nodes := graph.NodeList()
	openSet := &aStarPriorityQueue{}
	closedSet := set.NewSet()                 // This is to make use of that same
	costs = make(map[int]float64, len(nodes)) // May overallocate, will change if it becomes a problem
	predecessor := make(map[int]Node, len(nodes))
	nodeIDMap := make(map[int]Node, len(nodes))
	heap.Init(openSet)

	// I don't think we actually need the init step since I use a map check rather than inf to check if we're done
	/*for _, node := range nodes {
		if node == source {
			heap.Push(openSet, internalNode{node, 0, 0})
			costs[node] = 0
		} else {
			heap.Push(openSet, internalNode{node, math.MaxFloat64, math.MaxFloat64})
			predecessor[node] = -1
		}
	}*/

	costs[source.ID()] = 0
	heap.Push(openSet, internalNode{source, 0, 0})

	for openSet.Len() != 0 {
		node := heap.Pop(openSet).(internalNode)
		/* if _, ok := costs[node.int]; !ok {
			 break
		 } */

		if closedSet.Contains(node.ID()) { // As in A*, prevents us from having to slowly search and reorder the queue
			continue
		}

		nodeIDMap[node.ID()] = node

		closedSet.Add(node.ID())

		for _, neighbor := range graph.Successors(node) {
			tmpCost := costs[node.ID()] + Cost(node, neighbor)
			if cost, ok := costs[neighbor.ID()]; !ok || tmpCost < cost {
				costs[neighbor.ID()] = cost
				predecessor[neighbor.ID()] = node
				heap.Push(openSet, internalNode{neighbor, cost, cost})
			}
		}
	}

	paths = make(map[int][]Node, len(costs))
	for node, _ := range costs { // Only reconstruct the path if one exists
		paths[node] = rebuildPath(predecessor, nodeIDMap[node])
	}
	return paths, costs
}
Exemplo n.º 7
0
func TestRemove(t *testing.T) {
	s := set.NewSet()

	s.Add(1)
	s.Add(3)
	s.Add(5)

	s.Remove(1)

	if s.Cardinality() != 2 {
		t.Error("Incorrect number of set elements after removing an element")
	}

	if s.Contains(1) {
		t.Error("Element present after removal")
	}

	if !s.Contains(3) || !s.Contains(5) {
		t.Error("Set remove removed wrong element")
	}

	s.Remove(1)

	if s.Cardinality() != 2 || s.Contains(1) {
		t.Error("Double set remove does something strange")
	}

	s.Add(1)

	if s.Cardinality() != 3 || !s.Contains(1) {
		t.Error("Cannot add element after removal")
	}

}
Exemplo n.º 8
0
// Expands the first node it sees trying to find the destination. Depth First Search is *not* guaranteed to find the shortest path,
// however, if a path exists DFS is guaranteed to find it (provided you don't find a way to implement a Graph with an infinite depth)
func DepthFirstSearch(start, goal Node, graph Graph) []Node {
	closedSet := set.NewSet()
	openSet := xifo.GonumStack([]interface{}{start})
	predecessor := make(map[int]Node)

	for !openSet.IsEmpty() {
		c := openSet.Pop()

		curr := c.(Node)

		if closedSet.Contains(curr.ID()) {
			continue
		}

		if curr == goal {
			return rebuildPath(predecessor, goal)
		}

		closedSet.Add(curr.ID())

		for _, neighbor := range graph.Successors(curr) {
			if closedSet.Contains(neighbor.ID()) {
				continue
			}

			predecessor[neighbor.ID()] = curr
			openSet.Push(neighbor)
		}
	}

	return nil
}
Exemplo n.º 9
0
func TestProperSubset(t *testing.T) {
	s1 := set.NewSet()
	s2 := set.NewSet()

	s2.Add(1)
	s2.Add(2)

	if !set.ProperSubset(s1, s2) {
		t.Error("Empty set is not proper subset of another non-empty set")
	}

	s1.Add(1)
	if !set.ProperSubset(s1, s2) {
		t.Errorf("Set {1} is not proper subset of {1,2}")
	}

	s1.Add(2)
	if set.ProperSubset(s1, s2) {
		t.Errorf("Set {1,2} is proper subset of equal set {1,2}")
	}

	s1.Add(3)
	if set.ProperSubset(s1, s2) {
		t.Error("Set {1,2,3} registers as proper subset of {1,2}")
	}

	s2.Add(4)
	if set.ProperSubset(s1, s2) {
		t.Error("Set {1,2,3} registers as proper subset of {1,2,4}")
	}

	s2.Add(5)
	if set.ProperSubset(s1, s2) {
		t.Error("Set {1,2,3} registers as proper subset of {1,2,4,5}")
	}

	if set.ProperSubset(s1, s1) || set.ProperSubset(s2, s2) {
		t.Error("Sets register as proper subsets of themselves")
	}

	s3 := set.NewSet()

	if set.ProperSubset(s3, s3) {
		t.Error("Empty set registers as proper subset of itself")
	}
}
Exemplo n.º 10
0
// A Postdominates B if and only if all paths from B travel through A
//
// This returns all possible post-dominators for all nodes, it does not prune for strict postdominators, immediate postdominators etc
func PostDominators(end Node, graph Graph) map[int]*set.Set {
	allNodes := set.NewSet()
	nlist := graph.NodeList()
	dominators := make(map[int]*set.Set, len(nlist))
	for _, node := range nlist {
		allNodes.Add(node.ID())
	}

	for _, node := range nlist {
		dominators[node.ID()] = set.NewSet()
		if node.ID() == end.ID() {
			dominators[node.ID()].Add(end.ID())
		} else {
			dominators[node.ID()].Copy(allNodes)
		}
	}

	for somethingChanged := true; somethingChanged; {
		somethingChanged = false
		for _, node := range nlist {
			if node.ID() == end.ID() {
				continue
			}
			succs := graph.Successors(node)
			if len(succs) == 0 {
				continue
			}
			tmp := set.NewSet().Copy(dominators[succs[0].ID()])
			for _, succ := range succs[1:] {
				tmp.Intersection(tmp, dominators[succ.ID()])
			}

			dom := set.NewSet()
			dom.Add(node.ID())

			dom.Union(dom, tmp)
			if !set.Equal(dom, dominators[node.ID()]) {
				dominators[node.ID()] = dom
				somethingChanged = true
			}
		}
	}

	return dominators
}
Exemplo n.º 11
0
func TestEqual(t *testing.T) {
	s1 := set.NewSet()
	s2 := set.NewSet()

	if !set.Equal(s1, s2) {
		t.Error("Two different empty sets not equal")
	}

	s1.Add(1)
	if set.Equal(s1, s2) {
		t.Error("Two different sets with different elements not equal")
	}

	s2.Add(1)
	if !set.Equal(s1, s2) {
		t.Error("Two sets with same element not equal")
	}
}
Exemplo n.º 12
0
func TestCopy(t *testing.T) {
	s1 := set.NewSet()
	s2 := set.NewSet()

	s1.Add(1)
	s1.Add(2)
	s1.Add(3)

	s2.Copy(s1)

	if !set.Equal(s1, s2) {
		t.Fatalf("Two sets not equal after copy")
	}

	s2.Remove(1)

	if set.Equal(s1, s2) {
		t.Errorf("Mutating one set mutated another after copy")
	}
}
Exemplo n.º 13
0
func TestSelfCopy(t *testing.T) {
	s1 := set.NewSet()

	s1.Add(1)
	s1.Add(2)

	s1.Copy(s1)

	if s1.Cardinality() != 2 {
		t.Error("Something strange happened when copying into self")
	}
}
Exemplo n.º 14
0
func TestIntersectionSame(t *testing.T) {
	s1 := set.NewSet()
	s2 := set.NewSet()
	s3 := set.NewSet()

	s1.Add(2)
	s1.Add(3)

	s2.Add(2)
	s2.Add(3)

	s3.Intersection(s1, s2)

	if card := s3.Cardinality(); card != 2 {
		t.Errorf("Intersection of identical sets yields set of wrong cardinality %d", card)
	}

	if !s3.Contains(2) || !s3.Contains(3) {
		t.Error("Intersection of identical sets yields set of wrong elements")
	}
}
Exemplo n.º 15
0
func TestUnionSame(t *testing.T) {
	s1 := set.NewSet()
	s2 := set.NewSet()
	s3 := set.NewSet()

	s1.Add(1)
	s1.Add(2)

	s2.Add(1)
	s2.Add(2)

	s3.Union(s1, s2)

	if s3.Cardinality() != 2 {
		t.Error("Union of same sets yields set with wrong cardinality")
	}

	if !s3.Contains(1) || !s3.Contains(2) {
		t.Error("Union of same sets yields wrong elements")
	}
}
Exemplo n.º 16
0
func TestSubset(t *testing.T) {
	s1 := set.NewSet()
	s2 := set.NewSet()

	s2.Add(1)
	s2.Add(2)

	if !set.Subset(s1, s2) {
		t.Error("Empty set is not subset of another set")
	}

	s1.Add(1)
	if !set.Subset(s1, s2) {
		t.Errorf("Set {1} is not subset of {1,2}")
	}

	s1.Add(2)
	if !set.Subset(s1, s2) {
		t.Errorf("Set {1,2} is not subset of equal set {1,2}")
	}

	s1.Add(3)
	if set.Subset(s1, s2) {
		t.Error("Set {1,2,3} registers as subset of {1,2}")
	}

	s2.Add(4)
	if set.Subset(s1, s2) {
		t.Error("Set {1,2,3} registers as subset of {1,2,4}")
	}

	s2.Add(5)
	if set.Subset(s1, s2) {
		t.Error("Set {1,2,3} registers as subset of {1,2,4,5}")
	}

	if !set.Subset(s1, s1) || !set.Subset(s2, s2) {
		t.Error("Sets don't register as subsets of temselves")
	}
}
Exemplo n.º 17
0
// Also known as Tarjan's Strongly Connected Components Algorithm. This returns all the strongly connected components in the graph.
//
// A strongly connected component of a graph is a set of vertices where it's possible to reach any vertex in the set from any other (meaning there's a cycle between them)
//
// Generally speaking, a directed graph where the number of strongly connected components is equal to the number of nodes is acyclic, unless you count reflexive edges as a cycle (which requires only a little extra testing)
//
// An undirected graph should end up with as many SCCs as there are "islands" (or subgraphs) of connections, meaning having more than one strongly connected component implies that your graph is not fully connected.
func Tarjan(graph Graph) (sccs [][]Node) {
	index := 0
	vStack := &xifo.GonumStack{}
	stackSet := set.NewSet()
	sccs = make([][]Node, 0)

	nodes := graph.NodeList()
	lowlinks := make(map[int]int, len(nodes))
	indices := make(map[int]int, len(nodes))

	var strongconnect func(Node) []Node

	strongconnect = func(node Node) []Node {
		indices[node.ID()] = index
		lowlinks[node.ID()] = index
		index += 1

		vStack.Push(node)
		stackSet.Add(node.ID())

		for _, succ := range graph.Successors(node) {
			if _, ok := indices[succ.ID()]; !ok {
				strongconnect(succ)
				lowlinks[node.ID()] = int(math.Min(float64(lowlinks[node.ID()]), float64(lowlinks[succ.ID()])))
			} else if stackSet.Contains(succ) {
				lowlinks[node.ID()] = int(math.Min(float64(lowlinks[node.ID()]), float64(lowlinks[succ.ID()])))
			}
		}

		if lowlinks[node.ID()] == indices[node.ID()] {
			scc := make([]Node, 0)
			for {
				v := vStack.Pop()
				stackSet.Remove(v.(Node).ID())
				scc = append(scc, v.(Node))
				if v.(Node).ID() == node.ID() {
					return scc
				}
			}
		}

		return nil
	}

	for _, n := range nodes {
		if _, ok := indices[n.ID()]; !ok {
			sccs = append(sccs, strongconnect(n))
		}
	}

	return sccs
}
Exemplo n.º 18
0
func TestClear(t *testing.T) {
	s := set.NewSet()

	s.Add(8)
	s.Add(9)
	s.Add(10)

	s.Clear()

	if s.Cardinality() != 0 {
		t.Error("Clear did not properly reset set to size 0")
	}
}
Exemplo n.º 19
0
func TestSelfEqual(t *testing.T) {
	s := set.NewSet()

	if !set.Equal(s, s) {
		t.Error("Set is not equal to itself")
	}

	s.Add(1)

	if !set.Equal(s, s) {
		t.Error("Set ceases self equality after adding element")
	}
}
Exemplo n.º 20
0
// Generates a minimum spanning tree with sets.
//
// As with other algorithms that use Cost, the order of precedence is Argument > Interface > UniformCost
func Prim(dst MutableGraph, graph Graph, Cost func(Node, Node) float64) {
	if Cost == nil {
		if cgraph, ok := graph.(Coster); ok {
			Cost = cgraph.Cost
		} else {
			Cost = UniformCost
		}
	}
	dst.EmptyGraph()
	dst.SetDirected(false)

	nlist := graph.NodeList()

	if nlist == nil || len(nlist) == 0 {
		return
	}

	dst.AddNode(nlist[0], nil)
	remainingNodes := set.NewSet()
	for _, node := range nlist[1:] {
		remainingNodes.Add(node.ID())
	}

	edgeList := graph.EdgeList()
	for remainingNodes.Cardinality() != 0 {
		edgeWeights := make(edgeSorter, 0)
		for _, edge := range edgeList {
			if dst.NodeExists(edge.Head()) && remainingNodes.Contains(edge.Tail().ID()) {
				edgeWeights = append(edgeWeights, WeightedEdge{Edge: edge, Weight: Cost(edge.Head(), edge.Tail())})
			}
		}

		sort.Sort(edgeWeights)
		myEdge := edgeWeights[0]

		if !dst.NodeExists(myEdge.Head()) {
			dst.AddNode(myEdge.Head(), []Node{myEdge.Tail()})
		} else {
			dst.AddEdge(myEdge.Edge)
		}
		dst.SetEdgeCost(myEdge.Edge, myEdge.Weight)

		remainingNodes.Remove(myEdge.Edge.Head())
	}

}
Exemplo n.º 21
0
func TestAdd(t *testing.T) {
	s := set.NewSet()
	if s == nil {
		t.Fatal("Set cannot be created successfully")
	}

	if s.Cardinality() != 0 {
		t.Error("Set somehow contains new elements upon creation")
	}

	s.Add(1)
	s.Add(3)
	s.Add(5)

	if s.Cardinality() != 3 {
		t.Error("Incorrect number of set elements after adding")
	}

	if !s.Contains(1) || !s.Contains(3) || !s.Contains(5) {
		t.Error("Set doesn't contain element that was added")
	}

	s.Add(1)

	if s.Cardinality() > 3 {
		t.Error("Set double-adds element (element not unique)")
	} else if s.Cardinality() < 3 {
		t.Error("Set double-add lowered cardinality")
	}

	if !s.Contains(1) {
		t.Error("Set doesn't contain double-added element")
	}

	if !s.Contains(3) || !s.Contains(5) {
		t.Error("Set removes element on double-add")
	}

}
Exemplo n.º 22
0
func TestElements(t *testing.T) {
	s := set.NewSet()
	el := s.Elements()
	if el == nil {
		t.Errorf("Elements of empty set incorrectly returns nil and not zero-length slice")
	}

	if len(el) != 0 {
		t.Errorf("Elements of empty set has len greater than 0")
	}

	s.Add(1)
	s.Add(2)

	el = s.Elements()
	if len(el) != 2 {
		t.Fatalf("Elements not of same cardinality as set that spawned it")
	}

	if e, ok := el[0].(int); !ok {
		t.Errorf("Element in elements not of right type, %v", e)
	} else if e != 1 && e != 2 {
		t.Errorf("Element in elements has incorrect value %d", e)
	}

	if e, ok := el[1].(int); !ok {
		t.Errorf("Element in elements not of right type, %v", e)
	} else if e != 1 && e != 2 {
		t.Errorf("Element in elements has incorrect value %d", e)
	}

	el[0] = 19
	el[1] = 52

	if !s.Contains(1) || !s.Contains(2) || s.Cardinality() != 2 {
		t.Error("Mutating elements slice mutates set")
	}
}