private float EvaluatePosition(int depth, Dot player, float alpha, float beta) { if (depth == 0) { return(Estimator.Estimate(player)); } Dot nextPlayer = player.NextPlayer(); var moves = MoveGenerator.GenerateMovesForPlayer(player); foreach (var move in moves) { if (alpha < beta) { Field.MakeMove(move); float tmp = -EvaluatePosition(depth - 1, nextPlayer, -beta, -alpha); Field.UnmakeMove(); if (tmp > alpha) { alpha = tmp; } } } return(alpha); }
public void Evaluating4000Records_ExpectedTime_200ms() { // Arrange var engine = new V8ScriptEngine(); var exprected_time = TimeSpan.FromMilliseconds(200); var exprected_count = 4000; var actual_time = new TimeSpan(); var actual_results = new Stack <int>(4000); // Act try { actual_time = Estimator.Estimate(() => { for (int i = 0; i < 4000; i++) { actual_results.Push((int)engine.Evaluate("1+1")); } }); } finally { engine.Dispose(); } // Expect Assert.AreEqual(exprected_count, actual_results.Count); Assert.That(actual_time, Is.LessThanOrEqualTo(exprected_time)); }
private unsafe float EvaluatePosition(byte depth, Dot player, float alpha, float beta, ulong key, HashSet <int> moves) { float oldAlpha = alpha; Dot nextPlayer = player.NextPlayer(); float score = CheckCollision(player, depth, alpha, beta, key, moves); if (score >= 0) { return(score); } if (depth == 0) { return(Estimator.Estimate(player)); } foreach (var move in moves) { if (Field.MakeMove(move)) { HashField.UpdateHash(); float tmp = -EvaluatePosition((byte)(depth - 1), nextPlayer, -beta, -alpha, HashField.Key, MoveGenerator.GenerateMoves(nextPlayer, moves)); Field.UnmakeMove(); HashField.UpdateHash(); if (tmp > alpha) { TranspositionTable.RecordHash( (byte)depth, tmp, tmp < beta ? enmHashEntryType.Exact : enmHashEntryType.Beta, HashField.Key, (ushort)move); alpha = tmp; if (alpha >= beta) { return(beta); } } } } if (alpha == oldAlpha) { TranspositionTable.RecordHash((byte)depth, alpha, enmHashEntryType.Alpha, HashField.Key, 0); } return(alpha); }
public static IList <RecommendedItem> GetTopItems(int howMany, IEnumerable <Item> allItems, Rescorer <Item> rescorer, Estimator <Item> estimator) { if (allItems == null || rescorer == null || estimator == null) { throw new ArgumentNullException("argument is null"); } LinkedList <RecommendedItem> topItems = new LinkedList <RecommendedItem>(); bool full = false; foreach (Item item in allItems) { if (item.IsRecommendable && !rescorer.IsFiltered(item)) { double preference = estimator.Estimate(item); double rescoredPref = rescorer.Rescore(item, preference); LinkedListNode <RecommendedItem> node = topItems.Last; if (!Double.IsNaN(rescoredPref) && (!full || rescoredPref > node.Value.Value)) { // I think this is faster than Collections.binarySearch() over a LinkedList since our // comparisons are cheap, which binarySearch() economizes at the expense of more traversals. // We also know that the right position tends to be at the end of the list. while (node != null && node.Previous != null) { node = node.Previous; if (rescoredPref <= node.Value.Value) { node = node.Next; break; } if (node == topItems.First) { break; } } RecommendedItem newItem = new GenericRecommendedItem(item, rescoredPref); if (node == null) { topItems.AddFirst(newItem); } else if (topItems.Count == 1) { // special handling in this case is to avoid problems // with negative preferences. Imagine -0.3 being added // first followed by -0.6. If we simply did AddAfter, // those items would be out of sequence - cc if (rescoredPref > node.Value.Value) { topItems.AddAfter(node, newItem); } else { topItems.AddBefore(node, newItem); } } else { topItems.AddAfter(node, newItem); } if (full) { topItems.RemoveLast(); } else if (topItems.Count > howMany) { full = true; topItems.RemoveLast(); } } } } List <RecommendedItem> result = new List <RecommendedItem>(topItems.Count); foreach (RecommendedItem item in topItems) { result.Add(item); } return(result); }
public static List <User> GetTopUsers(int howMany, IEnumerable <User> allUsers, Rescorer <User> rescorer, Estimator <User> estimator) { LinkedList <SimilarUser> topUsers = new LinkedList <SimilarUser>(); bool full = false; foreach (User user in allUsers) { if (rescorer.IsFiltered(user)) { continue; } double similarity = estimator.Estimate(user); double rescoredSimilarity = rescorer.Rescore(user, similarity); LinkedListNode <SimilarUser> node = topUsers.Last; if (!double.IsNaN(rescoredSimilarity) && (!full || rescoredSimilarity > node.Value.Similarity)) { //SimilarUser _user = new SimilarUser(user, similarity); SimilarUser _user = new SimilarUser(user, rescoredSimilarity); if (node == null) { topUsers.AddLast(_user); } else if (node.Previous == null) // 1 node { if (rescoredSimilarity > node.Value.Similarity) { topUsers.AddAfter(node, _user); } else { topUsers.AddBefore(node, _user); } } else { while (node != null && node.Previous != null && (node != topUsers.First)) { node = node.Previous; if (rescoredSimilarity <= node.Value.Similarity) { topUsers.AddBefore(node, _user); break; } } } if (full) { topUsers.RemoveLast(); } else if (topUsers.Count > howMany) { full = true; topUsers.RemoveLast(); } } } List <User> result = new List <User>(topUsers.Count); foreach (SimilarUser similarUser in topUsers) { result.Add(similarUser.User); } return(result); }