public void TestSimple() { int size = 5; var heap = new ListHeap <int>(size); for (int ai = 0; ai < 10; ai++) { if (ai < size) { Assert.AreEqual(ai, heap.Size()); } else { Assert.AreEqual(size, heap.Size()); } heap.Add(ai); } Assert.AreEqual(0, heap.Extract()); Assert.AreEqual(4, heap.Size()); Assert.AreEqual(1, heap.Extract()); Assert.AreEqual(3, heap.Size()); Assert.AreEqual(2, heap.Extract()); Assert.AreEqual(2, heap.Size()); Assert.AreEqual(3, heap.Extract()); Assert.AreEqual(1, heap.Size()); Assert.AreEqual(4, heap.Extract()); Assert.AreEqual(0, heap.Size()); }
public void TestSimple() { int size = 5; var heap = new ListHeap<int>(size); for (int ai = 0; ai < 10; ai++) { if (ai < size) Assert.AreEqual(ai, heap.Size()); else Assert.AreEqual(size, heap.Size()); heap.Add(ai); } Assert.AreEqual(0, heap.Extract()); Assert.AreEqual(4, heap.Size()); Assert.AreEqual(1, heap.Extract()); Assert.AreEqual(3, heap.Size()); Assert.AreEqual(2, heap.Extract()); Assert.AreEqual(2, heap.Size()); Assert.AreEqual(3, heap.Extract()); Assert.AreEqual(1, heap.Size()); Assert.AreEqual(4, heap.Extract()); Assert.AreEqual(0, heap.Size()); }
/// <summary> /// Returns the best sequence of outcomes based on model for this object.</summary> /// <param name="numSequences"> /// The maximum number of sequences to be returned. /// </param> /// <param name="sequence"> /// The input sequence. /// </param> /// <param name="additionalContext"> /// An object[] of additional context. This is passed to the context generator blindly with the assumption that the context are appropiate. /// </param> /// <param name="minSequenceScore"> /// A lower bound on the score of a returned sequence.</param> /// <returns> /// An array of the top ranked sequences of outcomes. /// </returns> public virtual Sequence[] BestSequences(int numSequences, object[] sequence, object[] additionalContext, double minSequenceScore) { int sequenceCount = sequence.Length; ListHeap<Sequence> previousHeap = new ListHeap<Sequence>(Size); ListHeap<Sequence> nextHeap = new ListHeap<Sequence>(Size); ListHeap<Sequence> tempHeap; previousHeap.Add(new Sequence()); if (additionalContext == null) { additionalContext = mEmptyAdditionalContext; } for (int currentSequence = 0; currentSequence < sequenceCount; currentSequence++) { int sz = System.Math.Min(Size, previousHeap.Size); int sc = 0; for (; previousHeap.Size > 0 && sc < sz; sc++) { Sequence topSequence = previousHeap.Extract(); String[] outcomes = topSequence.Outcomes.ToArray(); String[] contexts = ContextGenerator.GetContext(currentSequence, sequence, outcomes, additionalContext); double[] scores; if (mContextsCache != null) { scores = (double[]) mContextsCache[contexts]; if (scores == null) { scores = Model.Evaluate(contexts, mProbabilities); mContextsCache[contexts] = scores; } } else { scores = Model.Evaluate(contexts, mProbabilities); } double[] tempScores = new double[scores.Length]; Array.Copy(scores, tempScores, scores.Length); Array.Sort(tempScores); double minimum = tempScores[System.Math.Max(0, scores.Length - Size)]; for (int currentScore = 0; currentScore < scores.Length; currentScore++) { if (scores[currentScore] < minimum) { continue; //only advance first "size" outcomes } string outcomeName = Model.GetOutcomeName(currentScore); if (ValidSequence(currentSequence, sequence, outcomes, outcomeName)) { Sequence newSequence = new Sequence(topSequence, outcomeName, scores[currentScore]); if (newSequence.Score > minSequenceScore) { nextHeap.Add(newSequence); } } } if (nextHeap.Size == 0) {//if no advanced sequences, advance all valid for (int currentScore = 0; currentScore < scores.Length; currentScore++) { string outcomeName = Model.GetOutcomeName(currentScore); if (ValidSequence(currentSequence, sequence, outcomes, outcomeName)) { Sequence newSequence = new Sequence(topSequence, outcomeName, scores[currentScore]); if (newSequence.Score > minSequenceScore) { nextHeap.Add(newSequence); } } } } //nextHeap.Sort(); } // make prev = next; and re-init next (we reuse existing prev set once we clear it) previousHeap.Clear(); tempHeap = previousHeap; previousHeap = nextHeap; nextHeap = tempHeap; } int topSequenceCount = System.Math.Min(numSequences, previousHeap.Size); Sequence[] topSequences = new Sequence[topSequenceCount]; int sequenceIndex = 0; for (; sequenceIndex < topSequenceCount; sequenceIndex++) { topSequences[sequenceIndex] = (Sequence) previousHeap.Extract(); } return topSequences; }
IEnumerator FindPath(Vector3 startPos, Vector3 targetPos) { Stopwatch sw = new Stopwatch(); sw.Start(); Vector3[] waypoints = new Vector3[0]; bool pathSuccess = false; QuadTreeNode startNode = grid.locateNode(startPos); QuadTreeNode targetNode = grid.locateNode(targetPos); //if ((targetNode.danger < 1 && targetNode.walkable)) if (startNode.walkable && targetNode.walkable) { ListHeap<QuadTreeNode> openSet = new ListHeap<QuadTreeNode>(); HashSet<QuadTreeNode> closedSet = new HashSet<QuadTreeNode>(); openSet.Add(startNode); while (openSet.Count > 0) { QuadTreeNode currentNode = openSet.RemoveFirst(); closedSet.Add(currentNode); if (currentNode == targetNode) { sw.Stop(); // print("Path found: " + sw.ElapsedMilliseconds + " ms"); pathSuccess = true; break; } foreach (KeyValuePair<QuadTreeNode, float> entry in currentNode.neighbours) { //if (neighbour.danger > 0 || !neighbour.walkable || closedSet.Contains(neighbour)) QuadTreeNode neighbour = entry.Key; if (!neighbour.walkable || closedSet.Contains(neighbour)) { continue; } float newMovementCostToNeighbour = currentNode.gCost + entry.Value; if (newMovementCostToNeighbour < neighbour.gCost || !openSet.Contains(neighbour)) { neighbour.gCost = newMovementCostToNeighbour; neighbour.hCost = Vector3.Distance(neighbour.worldPosition,targetNode.worldPosition); neighbour.successor = currentNode; if (!openSet.Contains(neighbour)) openSet.Add(neighbour); else openSet.UpdateItem(neighbour); } } } } yield return null; if (pathSuccess) { waypoints = RetracePath(startNode, targetNode); } requestManager.FinishedProcessingPath(waypoints, pathSuccess); }
/// <summary> /// Finds the n most probable sequences. /// </summary> /// <param name="numSequences">The number sequences.</param> /// <param name="sequence">The sequence.</param> /// <param name="additionalContext">The additional context.</param> /// <param name="minSequenceScore">The minimum sequence score.</param> /// <param name="beamSearch">The beam search.</param> /// <param name="validator">The validator.</param> public Sequence[] BestSequences(int numSequences, T[] sequence, object[] additionalContext, double minSequenceScore, IBeamSearchContextGenerator <T> beamSearch, ISequenceValidator <T> validator) { IHeap <Sequence> prev = new ListHeap <Sequence>(size); IHeap <Sequence> next = new ListHeap <Sequence>(size); prev.Add(new Sequence()); if (additionalContext == null) { additionalContext = new object[] {}; // EMPTY_ADDITIONAL_CONTEXT } for (var i = 0; i < sequence.Length; i++) { var sz = Math.Min(size, prev.Size()); for (var sc = 0; prev.Size() > 0 && sc < sz; sc++) { var top = prev.Extract(); var tmpOutcomes = top.Outcomes; var outcomes = tmpOutcomes.ToArray(); var contexts = beamSearch.GetContext(i, sequence, outcomes, additionalContext); double[] scores; if (contextsCache != null) { scores = (double[])contextsCache.Get(contexts); if (scores == null) { scores = model.Eval(contexts, probs); contextsCache.Put(contexts, scores); } } else { scores = model.Eval(contexts, probs); } var tempScores = new double[scores.Length]; for (var c = 0; c < scores.Length; c++) { tempScores[c] = scores[c]; } Array.Sort(tempScores); var min = tempScores[Math.Max(0, scores.Length - size)]; for (var p = 0; p < scores.Length; p++) { if (scores[p] < min) { continue; //only advance first "size" outcomes } var outcome = model.GetOutcome(p); if (validator.ValidSequence(i, sequence, outcomes, outcome)) { var ns = new Sequence(top, outcome, scores[p]); if (ns.Score > minSequenceScore) { next.Add(ns); } } } if (next.Size() == 0) { //if no advanced sequences, advance all valid for (var p = 0; p < scores.Length; p++) { var outcome = model.GetOutcome(p); if (validator.ValidSequence(i, sequence, outcomes, outcome)) { var ns = new Sequence(top, outcome, scores[p]); if (ns.Score > minSequenceScore) { next.Add(ns); } } } } } // make prev = next; and re-init next (we reuse existing prev set once we clear it) prev.Clear(); var tmp = prev; prev = next; next = tmp; } var numSeq = Math.Min(numSequences, prev.Size()); var topSequences = new Sequence[numSeq]; for (var seqIndex = 0; seqIndex < numSeq; seqIndex++) { topSequences[seqIndex] = prev.Extract(); } return(topSequences); }
IEnumerator FindPath(Vector3 startPos, Vector3 targetPos) { Stopwatch sw = new Stopwatch(); sw.Start(); Vector3[] waypoints = new Vector3[0]; bool pathSuccess = false; QuadTreeNode startNode = grid.locateNode(startPos); QuadTreeNode targetNode = grid.locateNode(targetPos); //if ((targetNode.danger < 1 && targetNode.walkable)) if (startNode.walkable && targetNode.walkable) { ListHeap <QuadTreeNode> openSet = new ListHeap <QuadTreeNode>(); HashSet <QuadTreeNode> closedSet = new HashSet <QuadTreeNode>(); openSet.Add(startNode); while (openSet.Count > 0) { QuadTreeNode currentNode = openSet.RemoveFirst(); closedSet.Add(currentNode); if (currentNode == targetNode) { sw.Stop(); // print("Path found: " + sw.ElapsedMilliseconds + " ms"); pathSuccess = true; break; } foreach (KeyValuePair <QuadTreeNode, float> entry in currentNode.neighbours) { //if (neighbour.danger > 0 || !neighbour.walkable || closedSet.Contains(neighbour)) QuadTreeNode neighbour = entry.Key; if (!neighbour.walkable || closedSet.Contains(neighbour)) { continue; } float newMovementCostToNeighbour = currentNode.gCost + entry.Value; if (newMovementCostToNeighbour < neighbour.gCost || !openSet.Contains(neighbour)) { neighbour.gCost = newMovementCostToNeighbour; neighbour.hCost = Vector3.Distance(neighbour.worldPosition, targetNode.worldPosition); neighbour.successor = currentNode; if (!openSet.Contains(neighbour)) { openSet.Add(neighbour); } else { openSet.UpdateItem(neighbour); } } } } } yield return(null); if (pathSuccess) { waypoints = RetracePath(startNode, targetNode); } requestManager.FinishedProcessingPath(waypoints, pathSuccess); }