Example #1
0
        /// <summary>
        /// The base constructor.
        /// </summary>
        /// <param name="domain">The base domain object.</param>
        /// <param name="problem">The base problem object.</param>
        /// <param name="path">The path used to save files to disk.</param>
        public MediationTree(Domain domain, Problem problem, string path)
        {
            // Store the domain, problem, and path.
            this.domain  = domain;
            this.problem = problem;
            this.path    = path;

            // Store the player's name.
            player = problem.Player.ToLower();

            // Get and store the NPC names.
            npcs = GetNPCs();

            // Establish the turn order.
            turnOrder = GetTurnOrder();

            // Create a new hashtable to store tree edges.
            tree = new Hashtable();

            // Initialize the session counters.
            nodeCounter    = 0;
            lowestDepth    = 0;
            goalStateCount = 0;
            deadEndCount   = 0;

            // Create the tree's root node.
            MediationTreeNode root = CreateNode(domain, problem, null);
        }
Example #2
0
        /// <summary>
        /// Given a mediation tree and a node in the tree, returns the node's world history.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="tree">The tree.</param>
        /// <returns>The path through the tree from the root to the node.</returns>
        public static List <MediationTreeNode> GetWorldHistory(MediationTreeNode node, MediationTree tree)
        {
            // Create an empty list object to hold the history.
            List <MediationTreeNode> history = new List <MediationTreeNode>();

            // Add the node to the world history.
            history.Add(node);

            // Remember the current node's ID.
            int current = node.ID;

            // While the current node's parent is not null...
            while (tree.GetParent(current) != -1)
            {
                // Store the current node's parent object.
                MediationTreeNode parent = tree.GetNode(tree.GetParent(current));

                // Remember the parent's ID.
                current = parent.ID;

                // Insert the parent node into the world history.
                history.Insert(0, parent);
            }

            // Return the world history.
            return(history);
        }
Example #3
0
        /// <summary>
        /// Write a node object to disk.
        /// </summary>
        /// <param name="node">The node's ID.</param>
        public void SetNode(MediationTreeNode node)
        {
            // Given the path and ID, write the node object to disk.
            BinarySerializer.SerializeObject <MediationTreeNode>(path + node.ID, node);

            // Save the mediation tree.
            SaveTree();
        }
Example #4
0
        /// <summary>
        /// Given a mediation tree and a node in the tree, returns a event revision domain and problem.
        /// </summary>
        /// <param name="node">The mediation tree node.</param>
        /// <param name="tree">The mediation tree.</param>
        /// <returns>The event revision problem and domain for the node.</returns>
        public static Tuple <Domain, Problem> GetEventRevisionPair(MediationTreeNode node, MediationTree tree)
        {
            // Create a clone of the node's original domain.
            Domain revisionDomain = node.Domain.Clone() as Domain;

            // Create a clone of the node's original problem.
            Problem revisionProblem = tree.Root.Problem.Clone() as Problem;

            // Get the series of actions and state literals the player has observed.
            List <Tuple <Operator, State> > playerKnowledge = GetWorldKnowledge(tree.Player, node, tree);

            // Rename the problem to the automated slot.
            revisionProblem.Name = "rob";

            // Add the initial state tracking literal to the problem's initial state.
            revisionProblem.Initial.Add(new Predicate("state-depth", new List <ITerm> {
                new Term("depth1", true)
            }, true));

            revisionDomain.AddTypePair("depth", "state");
            revisionDomain.Predicates.Add(new Predicate("state-depth", new List <ITerm> {
                new Term("?depth", "", "state")
            }, true));

            // For every operator in the cloned domain...
            foreach (Operator op in revisionDomain.Operators)
            {
                // Add a state tracking precondition that prevents it from being applied until after the event revision operations have been performed.
                op.Preconditions.Add(new Predicate("state-depth", new List <ITerm> {
                    new Term("depth" + playerKnowledge.Count.ToString(), true)
                }, true));
            }

            // Loop through the action-state pairs in the player knowledge.
            for (int i = 1; i < playerKnowledge.Count; i++)
            {
                // For each of these, add a new state tracker to the list of objects.
                revisionProblem.Objects.Add(new Obj("depth" + i.ToString(), "depth"));

                // If the player did not observed the current action, add a set of unobserved templates to the list of operators.
                if (playerKnowledge[i].First == null)
                {
                    revisionDomain.Operators.AddRange(GetUnobservedActionTemplates(i, tree.GetTurnAtIndex(i - 1), node.Domain, playerKnowledge[i - 1].Second));
                }
                // If the player did observe the current action, add the observed template to the list of operators.
                else
                {
                    revisionDomain.Operators.Add(GetObservedActionTemplate(i, playerKnowledge[i].First));
                }
            }

            // Add the final state tracking object to the problem.
            revisionProblem.Objects.Add(new Obj("depth" + playerKnowledge.Count.ToString(), "depth"));

            // Return the domain-problem pair.
            return(new Tuple <Domain, Problem> (revisionDomain, revisionProblem));
        }
Example #5
0
        /// <summary>
        /// Creates a new node object.
        /// </summary>
        /// <param name="domain">The node's domain.</param>
        /// <param name="problem">The node's problem.</param>
        /// <param name="incoming">The node's incoming edge.</param>
        /// <returns></returns>
        public MediationTreeNode CreateNode(Domain domain, Problem problem, MediationTreeEdge incoming)
        {
            // Create a placeholder for the new node object.
            MediationTreeNode node = null;

            // If the node is a root, initialize a root node.
            if (incoming == null)
            {
                node = new MediationTreeNode(domain, problem, 0);
            }
            // Otherwise, it is a child node...
            else
            {
                // Store the current node's ID in the incoming edge.
                incoming.Child = ++nodeCounter;

                // Create the new node object.
                node = new MediationTreeNode(domain, problem, incoming, GetSuccessorState(incoming), incoming.Child, GetDepth(incoming.Parent) + 1);

                // Add the edge to the tree hashtable.
                tree.Add(incoming.Child, incoming.Parent);
            }

            // If the node is a goal state, iterate the goal state counter.
            if (node.IsGoal)
            {
                goalStateCount++;
            }

            // If the node is at a lower depth than the previous record holder, update the depth counter.
            if (node.Depth > lowestDepth)
            {
                lowestDepth = node.Depth;
            }

            // Find and store the node's outgoing edges.
            node.Outgoing = GetOutgoingEdges(node, GetCurrentTurn(node));

            // Iterate through the node's outgoing edges.
            foreach (GameTreeEdge edge in node.Outgoing)
            {
                // And add each of them to the unplayed collection.
                node.Unplayed.Add(edge);
            }

            // Save the current node to disk.
            SetNode(node);

            // Return the current node object.
            return(node);
        }
Example #6
0
        /// <summary>
        /// The base constructor.
        /// </summary>
        /// <param name="planner">The planner to use.</param>
        /// <param name="domain">The base domain object.</param>
        /// <param name="problem">The base problem object.</param>
        /// <param name="path">The path used to save files to disk.</param>
        /// <param name="domainRevision">Whether to use domain revision.</param>
        /// <param name="eventRevision">Whether to use event revision.</param>
        /// <param name="superpositionManipulation">Whether to use superposition manipulation.</param>
        public MediationTree(Domain domain, Problem problem, string path, bool domainRevision, bool eventRevision, bool superpositionManipulation)
        {
            // Set the path.
            this.path = path;

            // Check each path to see if it exists. If not, create the folder.
            if (!File.Exists(path))
            {
                Directory.CreateDirectory(path);
            }

            // If data already exists, load it from memory.
            if (File.Exists(path + "mediationtree"))
            {
                data = BinarySerializer.DeSerializeObject <MediationTreeData>(path + "mediationtree");
            }
            // Otherwise, initialize a new tree.
            else
            {
                data.eventRevision             = eventRevision;
                data.domainRevision            = domainRevision;
                data.superpositionManipulation = superpositionManipulation;

                // Store the domain and problem.
                data.domain  = domain;
                data.problem = problem;

                // Store the player's name.
                data.player = problem.Player.ToLower();

                // Get and store the NPC names.
                data.npcs = GetNPCs();

                // Establish the turn order.
                data.turnOrder = GetTurnOrder();

                // Create a new hashtable to store tree edges.
                data.tree = new Hashtable();

                // Initialize the session counters.
                data.nodeCounter    = 0;
                data.lowestDepth    = 0;
                data.goalStateCount = 0;
                data.deadEndCount   = 0;

                // Create the tree's root node.
                MediationTreeNode root = CreateNode(domain, problem, null);
            }
        }
Example #7
0
        /// <summary>
        /// Creates a new node or returns the cached version.
        /// </summary>
        /// <param name="domain">The incoming domain.</param>
        /// <param name="problem">The incoming problem.</param>
        /// <param name="incoming">The incoming edge.</param>
        /// <returns>The child mediation tree node.</returns>
        public MediationTreeNode GetNode(Domain domain, Problem problem, MediationTreeEdge incoming)
        {
            // Return the cached child object if it has already been expanded.
            if (incoming.Child >= 0)
            {
                MediationTreeNode node = GetNode(incoming.Child);
                if (node != null)
                {
                    return(node);
                }
            }

            // Otherwise, return a new node.
            return(CreateNode(domain, problem, incoming));
        }
Example #8
0
        /// <summary>
        /// Returns a list of outgoing edges for a given node.
        /// </summary>
        /// <param name="node">The node object.</param>
        /// <param name="actor">The name of the current actor.</param>
        /// <returns>A list of outgoing edges.</returns>
        public List <MediationTreeEdge> GetOutgoingEdges(MediationTreeNode node, string actor)
        {
            List <MediationTreeEdge> outgoing = StateSpaceTools.GetAllPossibleActions(actor, node);

            if (!data.superpositionManipulation)
            {
                return(outgoing);
            }

            List <MediationTreeEdge> unobservedActions = new List <MediationTreeEdge>();
            List <MediationTreeEdge> observedActions   = new List <MediationTreeEdge>();

            foreach (MediationTreeEdge edge in outgoing)
            {
                Superposition super = node.State as Superposition;
                bool          obs   = false;
                foreach (State state in super.States)
                {
                    if (state.Satisfies(edge.Action.Preconditions))
                    {
                        if (KnowledgeAnnotator.Observes(Player, edge.Action, state.Predicates))
                        {
                            observedActions.Add(edge);
                            obs = true;
                            break;
                        }
                    }
                }

                if (!obs)
                {
                    unobservedActions.Add(edge);
                }
            }

            if (unobservedActions.Count > 0)
            {
                VirtualMediationTreeEdge super = new VirtualMediationTreeEdge();
                foreach (MediationTreeEdge unobserved in unobservedActions)
                {
                    super.Actions.Add(unobserved.Action as Operator);
                }
                super.Parent = node.ID;
                observedActions.Add(super);
            }

            return(observedActions);
        }
Example #9
0
        /// <summary>
        /// Given a planner, a mediation tree node, and a mediation tree, return an event revision plan and state to set for the node.
        /// </summary>
        /// <param name="planner">The planner to use.</param>
        /// <param name="node">The current node in the mediation tree.</param>
        /// <param name="tree">The mediation tree.</param>
        /// <returns>A plan state pair for the current node.</returns>
        public static void EventRevision(Planner planner, MediationTreeNode node, MediationTree tree)
        {
            // Compute the event revision problem and domain for the current node.
            Tuple <Domain, Problem> pair = GetEventRevisionPair(node, tree);

            // Use the planner to find an event revision plan.
            Plan plan = PlannerInterface.Plan(planner, pair.First, pair.Second);

            if (plan.Steps.Count > 0)
            {
                Tuple <Plan, State> planState = GetPlanStatePair(plan, node, tree);
                node.Plan            = planState.First;
                node.State           = planState.Second;
                node.Problem.Initial = node.State.Predicates;
            }
        }
Example #10
0
        /// <summary>
        /// Given an event revision plan, a mediation tree node, and a mediation tree, returns the plan and state to set in the node.
        /// </summary>
        /// <param name="plan">The full event revision plan from the original initial state.</param>
        /// <param name="node">The current node in the mediation tree.</param>
        /// <param name="tree">The mediation tree object.</param>
        /// <returns>The current state to set in the node after event revision and the plan from the state forward.</returns>
        public static Tuple <Plan, State> GetPlanStatePair(Plan plan, MediationTreeNode node, MediationTree tree)
        {
            // Reformat the event revision plan to get a regular plan.
            Plan formattedPlan = ReformatPlan(plan, tree.Root.Domain, tree.Root.Problem);

            // Create a list to hold event revision steps.
            List <IOperator> pastSteps = new List <IOperator>();

            // Create another list to hold future plan steps.
            List <IOperator> futureSteps = new List <IOperator>();

            // Loop through the steps in the formatted event revision plan...
            for (int i = 0; i < formattedPlan.Steps.Count; i++)
            {
                // If the step happened before the current state, it is an event revision step.
                if (i < node.Depth)
                {
                    pastSteps.Add(formattedPlan.Steps[i]);
                }
                // If the step happens at or after the current state, it is a future plan step.
                else
                {
                    futureSteps.Add(formattedPlan.Steps[i]);
                }
            }

            // Create a new state object by cloning the initial state of the original planning problem.
            State current = tree.Root.State.Clone() as State;

            // Loop through each of the event revision steps...
            foreach (IOperator step in pastSteps)
            {
                // And update the state object by applying the action.
                current = new State(current.ApplyAction(step as Operator, node.Problem.Objects));
            }

            // Return the future plan along with the computed state.
            return(new Tuple <Plan, State>(new Plan(node.Domain, node.Problem, futureSteps), current));
        }
Example #11
0
 /// <summary>
 /// Get the current turn taker.
 /// </summary>
 /// <param name="node">The current node.</param>
 /// <returns>The name of the character who gets to act.</returns>
 private string GetCurrentTurn(MediationTreeNode node)
 {
     // Returns the character who gets to act at this level.
     return(data.turnOrder[node.Depth % data.turnOrder.Count]);
 }
Example #12
0
        /// <summary>
        /// Allows custom plans to be passed in.
        /// </summary>
        /// <param name="domain">The node's domain.</param>
        /// <param name="problem">The node's problem.</param>
        /// <param name="incoming">The node's incoming edge.</param>
        /// <returns>A new tree node.</returns>
        private MediationTreeNode CreateNode(Domain domain, Problem problem, MediationTreeEdge incoming, Plan plan)
        {
            // Create a placeholder for the new node object.
            MediationTreeNode node = null;

            // If the node is a root, initialize a root node.
            if (incoming == null)
            {
                if (!data.superpositionManipulation)
                {
                    node = new MediationTreeNode(domain, problem, 0);
                }
                else
                {
                    node = new VirtualMediationTreeNode(domain, problem, 0);
                }
            }
            // Otherwise, it is a child node...
            else
            {
                // Store the current node's ID in the incoming edge.
                incoming.Child = ++data.nodeCounter;

                if (!data.superpositionManipulation)
                {
                    node = new MediationTreeNode(domain, problem, incoming, GetSuccessorState(incoming), plan, incoming.Child, GetDepth(incoming.Parent) + 1);
                }
                else
                {
                    node = new VirtualMediationTreeNode(domain, problem, incoming, GetSuccessorSuperposition(incoming), plan, incoming.Child, GetDepth(incoming.Parent) + 1);
                }

                // Add the edge to the tree hashtable.
                data.tree[incoming.Child] = incoming.Parent;

                MediationTreeNode parent = GetNode(incoming.Parent);
                if (incoming.Action != null)
                {
                    parent.Outgoing.Find(x => x.Action.Equals(incoming.Action)).Child = node.ID;
                }
                else
                {
                    foreach (MediationTreeEdge edge in parent.Outgoing)
                    {
                        if (edge is VirtualMediationTreeEdge)
                        {
                            if ((edge as VirtualMediationTreeEdge).Equals(incoming as VirtualMediationTreeEdge))
                            {
                                edge.Child = node.ID;
                            }
                        }
                    }
                }

                SetNode(parent);

                if (data.superpositionManipulation)
                {
                    Superposition super = node.State as Superposition;
                    super.States = SuperpositionManipulator.Collapse(data.player, node as VirtualMediationTreeNode, SuperpositionChooser.ChooseUtility);
                    node.State   = super;
                }
            }

            // If the node is a goal state, iterate the goal state counter.
            if (node.IsGoal)
            {
                data.goalStateCount++;
            }

            // If the node is a dead end, iterate the dead end counter.
            if (node.DeadEnd)
            {
                if (data.eventRevision)
                {
                    EventRevisor.EventRevision(Planner.FastDownward, node, this);
                }

                if (node.DeadEnd && data.domainRevision)
                {
                    DomainRevisor.DomainRevision(Planner.FastDownward, node, this);
                }

                if (node.DeadEnd)
                {
                    data.deadEndCount++;
                }
            }

            // If the node is at a lower depth than the previous record holder, update the depth counter.
            if (node.Depth > data.lowestDepth)
            {
                data.lowestDepth = node.Depth;
            }

            // If the node is not a dead end.
            if (!node.DeadEnd)
            {
                // Find and store the node's outgoing edges.
                node.Outgoing = GetOutgoingEdges(node, GetCurrentTurn(node));
            }

            // Save the current node to disk.
            SetNode(node);

            // Return the current node object.
            return(node);
        }
Example #13
0
        public static void DomainRevision(Planner planner, MediationTreeNode node, MediationTree tree)
        {
            // Store the incoming action.
            Operator incoming = node.Incoming.Action as Operator;

            // Create a new plan object.
            Plan newPlan = new Plan();

            List <Tuple <Operator, State> > knowledge = EventRevisor.GetWorldKnowledge(tree.Player, node, tree);

            knowledge.RemoveAt(knowledge.Count - 1);
            List <Operator> observedActions = new List <Operator>();

            foreach (Tuple <Operator, State> pair in knowledge)
            {
                if (pair.First != null)
                {
                    if (pair.First.Name.Equals(incoming.Name))
                    {
                        observedActions.Add(pair.First);
                    }
                }
            }

            // Examine each exceptional effect.
            foreach (Predicate effect in incoming.ExceptionalEffects)
            {
                // Create a new domain object.
                Domain newDomain = node.Domain.Clone() as Domain;
                newDomain.Operators = new List <IOperator>();

                // If the current effect is conditional...
                if (incoming.IsConditional(effect))
                {
                    bool observed = false;

                    // If the conditional effect has not been observed by the player.
                    foreach (Operator action in observedActions)
                    {
                        if (!observed)
                        {
                            foreach (IAxiom conditional in action.Conditionals)
                            {
                                if (conditional.Effects.Contains(effect) && !observed)
                                {
                                    observed = true;
                                }
                            }
                        }
                    }

                    // Remove the conditional effect from the domain.

                    if (!observed)
                    {
                        // Copy the current operator templates into a list.
                        List <IOperator> templates = new List <IOperator>();
                        foreach (IOperator templ in node.Domain.Operators)
                        {
                            templates.Add(templ.Clone() as IOperator);
                        }

                        // Create a clone of the incoming action's unbound operator template.
                        IOperator temp = incoming.Template() as Operator;

                        // Find the incoming action template in the domain list.
                        Operator template = templates.Find(t => t.Equals(temp)) as Operator;

                        // Remove the incoming action template from the domain list.
                        templates.Remove(template);

                        // Create a clone of the incoming action.
                        Operator clone = incoming.Clone() as Operator;

                        // Create a list of conditional effects to remove from the template.
                        List <IAxiom> remove = new List <IAxiom>();
                        foreach (IAxiom conditional in clone.Conditionals)
                        {
                            if (conditional.Effects.Contains(effect))
                            {
                                remove.Add(conditional);
                            }
                        }

                        // Remove each conditional effect from the template.
                        foreach (IAxiom rem in remove)
                        {
                            template.Conditionals.Remove(rem.Template() as IAxiom);
                        }

                        // Add the modified template to the domain list.
                        templates.Add(template);

                        // Push the modified list to the new domain object.
                        newDomain.Operators = templates;

                        // Clone the modified incoming action template.
                        Operator newAction = template.Clone() as Operator;

                        // Bind the cloned action with the incoming action's bindings.
                        newAction.Bindings = incoming.Bindings;

                        MediationTreeEdge newEdge = new MediationTreeEdge(newAction, ActionType.Exceptional, node.Incoming.Parent, node.ID);

                        Problem newProblem = node.Problem.Clone() as Problem;
                        newProblem.Initial = tree.GetSuccessorState(newEdge).Predicates;

                        // Find a new plan.
                        newPlan = PlannerInterface.Plan(planner, newDomain, newProblem);

                        // If the modified domain can accommodate the player's action...
                        if (newPlan.Steps.Count > 0)
                        {
                            node.Plan            = newPlan;
                            node.Incoming.Action = newAction;
                            node.State           = tree.GetSuccessorState(node.Incoming);
                            node.Domain          = newDomain;
                        }
                    }
                }
            }
        }
Example #14
0
 /// <summary>
 /// Returns a list of outgoing edges for a given node.
 /// </summary>
 /// <param name="node">The node object.</param>
 /// <param name="actor">The name of the current actor.</param>
 /// <returns>A list of outgoing edges.</returns>
 public List <MediationTreeEdge> GetOutgoingEdges(MediationTreeNode node, string actor)
 {
     // If it's the player's turn, return their list of actions.
     return(StateSpaceTools.GetAllPossibleActions(actor, node));
 }
Example #15
0
        /// <summary>
        /// Given a character, node, and tree, returns the character's knowledge of the world history.
        /// </summary>
        /// <param name="character">The character.</param>
        /// <param name="node">The node that corresponds to the current state.</param>
        /// <param name="tree">The mediation tree.</param>
        /// <returns>A list of action-state pairs that represent what the character knows.</returns>
        public static List <Tuple <Operator, State> > GetWorldKnowledge(string character, MediationTreeNode node, MediationTree tree)
        {
            // An object to hold the character's knowledge of the world history.
            List <Tuple <Operator, State> > knowledge = new List <Tuple <Operator, State> >();

            // Get the objective world history.
            List <MediationTreeNode> history = GetWorldHistory(node, tree);

            // Loop through the nodes in the world history branch...
            foreach (MediationTreeNode current in history)
            {
                // Create a new action.
                Operator action = null;

                // Make sure the current node is not the root.
                if (current.Incoming != null)
                {
                    // Check if the character observes the incoming action.
                    if (KnowledgeAnnotator.Observes(character, current.Incoming.Action, current.State.Predicates))
                    {
                        // If so, remember that the character observed the action.
                        action = current.Incoming.Action.Clone() as Operator;
                    }
                }

                // Create a new state consisting only of terms the character observed.
                State state = new State(KnowledgeAnnotator.FullKnowledgeState(tree.Root.Domain.Predicates, tree.Root.Problem.ObjectsByType, current.State.Predicates, character));

                // Store the observed action-state pair as a tuple.
                knowledge.Add(new Tuple <Operator, State>(action, state));
            }

            // Return the sequence of observed action-state pairs.
            return(knowledge);
        }
Example #16
0
        /// <summary>
        /// Chooses a set of superposed states based on a simple utility function.
        /// </summary>
        /// <param name="observations">The sets of possible literals observed by the player mapped to the sets of states consistent with each observation.</param>
        /// <param name="node">The current node in the mediation tree.</param>
        /// <returns>A set of states chosen by the system.</returns>
        public static HashSet <State> ChooseUtility(Dictionary <List <IPredicate>, HashSet <State> > observations, MediationTreeNode node)
        {
            // Create a dictionary of utilities that map to sets of states.
            Dictionary <float, HashSet <State> > utilities = new Dictionary <float, HashSet <State> >();

            // If there is more than one observation the player can make.
            if (observations.Keys.Count > 1)
            {
                // Loop through each set of observed literals.
                foreach (List <IPredicate> key in observations.Keys)
                {
                    // Store how many wins and losses the set of states has.
                    float wins   = 0;
                    float losses = 0;

                    // Loop through each state in the set of states consistent with the current observation.
                    foreach (State state in observations[key])
                    {
                        // Store whether we are at a goal state.
                        bool satisfiesGoal = false;

                        // Store whether a goal state is reached by the planner.
                        bool win = true;

                        // Check whether the current state is a goal state.
                        if (state.Satisfies(node.Problem.Goal))
                        {
                            satisfiesGoal = true;
                        }

                        // Create a new problem object for the current state.
                        Problem problem = new Problem("rob", node.Problem.OriginalName, node.Problem.Domain, node.Problem.Player, node.Problem.Objects, state.Predicates, node.Problem.Intentions, node.Problem.Goal);

                        // Find a plan from the current state if one exists.
                        Plan plan = PlannerInterface.Plan(Planner.FastDownward, node.Domain, problem);

                        // Check if a goal has been reached by the state or the plan.
                        if (plan.Steps.Count == 0 && !satisfiesGoal)
                        {
                            win = false;
                        }

                        // Record the win or loss.
                        if (win)
                        {
                            wins++;
                        }
                        else
                        {
                            losses++;
                        }
                    }

                    // Initialize the utility.
                    float utility = 0;

                    // If none of the states lost, go ahead and return the current state.
                    if (losses == 0)
                    {
                        return(observations[key]);
                    }
                    // Otherwise, record the utility as wins divided by losses.
                    else
                    {
                        utility = wins / losses;
                    }

                    // Map the utility onto the current state set in the dictionary.
                    utilities[utility] = observations[key];
                }
            }
            else
            {
                // Store the single set of observations.
                List <IPredicate> key = observations.Keys.ToArray()[0];

                // Use the observations to return the single set of states.
                return(observations[key]);
            }

            // Return the set of states with the highest utility value.
            return(utilities[utilities.Keys.Max()]);
        }
Example #17
0
        /// <summary>
        /// Randomly chooses a set of superposed states.
        /// </summary>
        /// <param name="observations">The sets of possible literals observed by the player mapped to the sets of states consistent with each observation.</param>
        /// <param name="node">The current node in the mediation tree.</param>
        /// <returns>A set of states chosen by the system.</returns>
        public static HashSet <State> ChooseRandom(Dictionary <List <IPredicate>, HashSet <State> > observations, MediationTreeNode node)
        {
            // Create a new Random object.
            Random rand = new Random();

            // Choose a random number to map onto a key in the observation dictionary.
            int pickNum = rand.Next(0, observations.Keys.Count);

            // Grab the observation set associated with the chosen integer.
            List <IPredicate> pickPreds = observations.Keys.ToArray()[pickNum];

            // Return the set of states consistent with the observation.
            return(observations[pickPreds]);
        }