Ejemplo n.º 1
0
    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;
    }
Ejemplo n.º 2
0
 /// <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;
 }
Ejemplo n.º 3
0
 /// <summary>
 /// Picks far away nodes
 /// </summary>
 public static double Score_Distance(
     ExplorationNode current,
     ExplorationNode candidate)
 {
     return 1.0 / current.GetPathOut(candidate.Id).Length;
 }
Ejemplo n.º 4
0
        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;
            }
        }