private static double ScoreNodeSkinnyPipe( ExplorationNode current, ExplorationNode candidate) { int length = current.GetPathOut(candidate.Id).Length; int minCutOut = current.GetMinCutOut(candidate.Id); double modifier = ScorePath(current.GetPathOut(candidate.Id)); return ((double)minCutOut / (double)length) / modifier; }
/// <summary> /// Picks far away nodes with a thin bottleneck /// </summary> public static double Score_SkinnyPipe( ExplorationNode current, ExplorationNode candidate) { int length = current.GetPathOut(candidate.Id).Length; int minCutOut = current.GetMinCutOut(candidate.Id); return (double)minCutOut / (double)length; }
/// <summary> /// Picks far away nodes /// </summary> public static double Score_Distance( ExplorationNode current, ExplorationNode candidate) { return 1.0 / current.GetPathOut(candidate.Id).Length; }
public static IEnumerable<Candidate> GetCandidates( ExplorationSpace space, ExplorationNode start, ExplorationNode lastGoal, HashSet<uint> busyObjects, Scorer scorer, int numRecommendations, bool descending) { if (busyObjects == null) busyObjects = new HashSet<uint>(); List<Candidate> candidates = new List<Candidate>(); foreach (ExplorationNode node in space.Nodes) { if (start == node) continue; // Make sure it's reachable ExplorationEdge[] path = start.GetPathOut(node.Id); if (path != null) { // Add it as a candidate if the score is high enough double score = scorer(start, node); ExplorationEdge edge = path[0]; ExplorationNode goal = path.Last().Target; double sentimentScore = SentimentScore(score, path); candidates.Add(new Candidate(path, goal, sentimentScore)); } } // Sort the candidates by score candidates.Sort((c1, c2) => c1.Score.CompareTo(c2.Score)); if (descending == true) candidates.Reverse(); // Add the previous goal to the front if we still have a path to it if (lastGoal != null) { ExplorationEdge[] oldPath = start.GetPathOut(lastGoal.Id); if (oldPath != null) candidates.Insert(0, new Candidate(oldPath, lastGoal, 0.0)); } HashSet<ExplorationNode> seenGoals = new HashSet<ExplorationNode>(); HashSet<ExplorationEdge> seenEdges = new HashSet<ExplorationEdge>(); // Pick the top N int count = 0; foreach (Candidate candidate in candidates) { ExplorationNode goal = candidate.Goal; if (candidate.Path.Length == 0) continue; ExplorationEdge edge = candidate.Path[0]; // Nix this event if it uses an object that's currently in use // TODO: Assumes only one event per edge TransitionEvent evt = edge.Events[0]; foreach (uint id in evt.Participants) if (busyObjects.Contains(id) == true) goto skipCandidate; // If this is a novel direction to go, add it bool seenGoal = seenGoals.Contains(goal); bool seenEdge = seenEdges.Contains(edge); if (seenGoal == false && seenEdge == false) { seenGoals.Add(goal); seenEdges.Add(edge); count++; yield return candidate; } if (count >= numRecommendations) break; skipCandidate : continue; } }