예제 #1
0
func (g *Graph) Traverse(privateState PrivateTraverseState, from, to *Node) (path []*Node, totalCost float64, ok bool) {
	seen := make(map[*Node]bool)

	state := &PublicTraverseState{0.0, from, &VisitedList{from, nil}, privateState}

	sh := sheap.NewSliceHeap(PublicStateLessThan)
	heap.Init(sh)
	heap.Push(sh, state)

	for !sh.IsEmpty() {
		state = heap.Pop(sh).(*PublicTraverseState)
		if _, found := seen[state.node]; found {
			continue
		}
		seen[state.node] = true

		if DEBUG&PROGRESSIVE_FLAG != 0 {
			fmt.Printf("%f : %s\n", state.totalCost, state.node.Record)
		}

		if state.node == to {
			return state.visited.MakeSlice(), state.totalCost, true
		}

		for _, vertex := range state.node.vertices {
			if DEBUG&TRAVERSE_FLAG != 0 {
				fmt.Printf("Considering %s to %s ... ", state.node.Record, vertex.To.Record)
			}
			totalCost := state.totalCost + vertex.Cost
			nextNode := vertex.To
			if state.visited.HasVisited(nextNode) {
				if DEBUG&TRAVERSE_FLAG != 0 {
					fmt.Println("already been there")
				}
				continue
			}
			nextPrivateState, ok := (state.privateState).TraverseStateHelper(vertex)
			if !ok {
				if DEBUG&TRAVERSE_FLAG != 0 {
					fmt.Println("rejected by calling code")
				}
				continue
			}
			nextPublicState := &PublicTraverseState{totalCost, nextNode, &VisitedList{nextNode, state.visited}, nextPrivateState}
			heap.Push(sh, nextPublicState)

			if DEBUG&TRAVERSE_FLAG != 0 {
				fmt.Printf("good w/ total cost of %f\n", totalCost)
			}
		}
	}

	return nil, 0.0, false
}
예제 #2
0
func NewPriorityQueue(f func(a, b interface{}) bool) *PriorityQueue {
	sh := sheap.NewSliceHeap(f)
	heap.Init(sh)
	return &PriorityQueue{sh}
}