Exemple #1
0
        private void Swap(int indexOne, int indexTwo)
        {
            PlannerState temp = Heap[indexOne];

            Heap[indexOne] = Heap[indexTwo];
            Heap[indexTwo] = temp;
        }
Exemple #2
0
 private bool CompareGreaterThan(PlannerState left, PlannerState right)
 {
     if (left.fCost == right.fCost)
     {
         return(left.hCost > right.hCost);
     }
     return(left.fCost > right.fCost);
 }
Exemple #3
0
 public PlannerState(S state, PlannerState previousState, A action, int gCost, int hCost)
 {
     this.state         = state;
     this.previousState = previousState;
     this.action        = action;
     this.gCost         = gCost;
     this.hCost         = hCost;
 }
Exemple #4
0
        public override bool Equals(object obj)
        {
            if (obj == null || GetType() != obj.GetType())
            {
                return(false);
            }
            PlannerState p = (PlannerState)obj;

            return(state.Equals(p.state));
        }
Exemple #5
0
    /// <summary>
    /// 直前のCompoundTaskの状態まで遡れるように、現在のPlannerStateを記録
    /// </summary>
    private void RecordDecompositionOfTask(CompoundTask nextCompoundTask)
    {
        var copyOfPlannerState = new PlannerState(
            plannerState.WorkingWS.Clone(),
            new List <TaskBase>(plannerState.FinalPlanList),
            new List <TaskBase>(plannerState.TaskListToProcess),
            plannerState.NextMethodNumber);

        copyOfPlannerState.TaskListToProcess.Add(nextCompoundTask);
        plannerStateHistory.Add(copyOfPlannerState);
    }
Exemple #6
0
    private List <A> RetraceActions(PlannerState plannerState)
    {
        List <A> actionSequence = new List <A>();

        while (plannerState.previousState != null)
        {
            actionSequence.Add(plannerState.action);
            plannerState = plannerState.previousState;
        }
        actionSequence.Reverse();
        return(actionSequence);
    }
Exemple #7
0
    private void RestoreToLastDecomposedTask()
    {
        // これ以上過去のPlannerStateに遡れない場合、Planningを終了させる
        if (plannerStateHistory.Count == 0)
        {
            plannerState.TaskListToProcess.Clear();
            return;
        }

        plannerState = plannerStateHistory.Last();
        plannerStateHistory.RemoveAt(plannerStateHistory.Count - 1);
    }
Exemple #8
0
        public PlannerState Pop()
        {
            if (Heap.Count == 0)
            {
                return(null);
            }

            PlannerState state = Heap[0];

            Heap[0] = Heap[Heap.Count - 1];
            Heap.RemoveAt(Heap.Count - 1);

            HeapifyDown();
            return(state);
        }
Exemple #9
0
    public List <TaskBase> Planning(IWorldState currentState, TaskBase rootTask)
    {
        plannerStateHistory.Clear();
        plannerState = new PlannerState(
            currentState.Clone(),
            new List <TaskBase>(),
            new List <TaskBase>()
        {
            rootTask
        },
            0);

        while (plannerState.TaskListToProcess.Count > 0)
        {
            var currentTask = plannerState.TaskListToProcess[0];
            Debug.Log("CurrentTask:" + currentTask);
            if (currentTask is CompoundTask currentCompoundTask)
            {
                var satisfiedMethod = FindSatisfiedMethod(currentCompoundTask, plannerState);
                if (satisfiedMethod != null)
                {
                    RecordDecompositionOfTask(currentCompoundTask);
                    plannerState.TaskListToProcess.RemoveAt(0);
                    plannerState.TaskListToProcess.InsertRange(0, satisfiedMethod.SubTasks);
                }
                else
                {
                    RestoreToLastDecomposedTask();
                }
            }
            else // PrimitiveTask
            {
                if (currentTask.CheckPreCondition(plannerState.WorkingWS))
                {
                    plannerState.TaskListToProcess.RemoveAt(0);
                    plannerState.FinalPlanList.Add(currentTask);
                    plannerState.WorkingWS = currentTask.ApplyEffects(plannerState.WorkingWS);
                }
                else
                {
                    RestoreToLastDecomposedTask();
                }
            }
        }

        return(new List <TaskBase>(plannerState.FinalPlanList));
    }
Exemple #10
0
    /// <summary>
    /// CompoundTaskが保有しているMethodの中から、現在のWorldStateに合致するMethodを返す。
    /// なければ、nullを返す。
    /// </summary>
    private Method FindSatisfiedMethod(CompoundTask currentCompoundTask, PlannerState plannerState)
    {
        var methodsWorldState = plannerState.WorkingWS.Clone();
        var methods           = currentCompoundTask.Methods;

        while (plannerState.NextMethodNumber < methods.Count)
        {
            var method = methods[plannerState.NextMethodNumber];
            plannerState.NextMethodNumber++;

            if (method.CheckPreCondition(methodsWorldState))
            {
                return(method);
            }
        }

        return(null);
    }
Exemple #11
0
        void SaveHistory(List <Task> taskQueue, List <PrimitiveTask> plan, List <StateVariable> state)
        {
            PlannerState ps;

            if (plannerStatePool.Count > 0)
            {
                ps = plannerStatePool.Pop();
            }
            else
            {
                ps = new PlannerState();
            }

            ps.queue.AddRange(taskQueue);
            ps.plan.AddRange(plan);
            foreach (var i in state)
            {
                ps.state.Add(i.value);
            }
            history.Push(ps);
        }
Exemple #12
0
    // TODO: actions should be a set (?)
    public Plan <T, S, A> GeneratePlan(Goal <S> goal, S state, List <A> actions)
    {
        // TODO: Sort actions based on cost

        PlannerStateHeap openSet   = new PlannerStateHeap();
        HashSet <S>      closedSet = new HashSet <S>();

        openSet.Add(new PlannerState(state, null, null, 0, goal.CalculateHCost(state)));

        while (openSet.Count > 0)
        {
            PlannerState currentState = openSet.Pop();
            if (closedSet.Contains(currentState.state))
            {
                continue;
            }
            closedSet.Add(currentState.state);

            if (goal.ValidateState(currentState.state))
            {
                return(new Plan <T, S, A>(goal, RetraceActions(currentState)));
            }

            for (int i = 0; i < actions.Count; i++)
            {
                S newState = actions[i].UpdateState(currentState.state.DeepClone());
                if (!closedSet.Contains(newState) && actions[i].ValidateState(currentState.state))
                {
                    int          newGCost        = currentState.gCost + actions[i].GetCost();
                    int          hCost           = goal.CalculateHCost(newState);
                    PlannerState newPlannerState = new PlannerState(newState, currentState, actions[i], newGCost, hCost);
                    openSet.Add(newPlannerState);
                }
            }
        }
        return(null);
    }
        public void dumpPlanToConsole(PlannerState final)
        {
            Console.WriteLine("UGLY REVERSE TIME PLAN DUMP");
            PlannerState s = final;

            while (s.parent != null)
            {
                if (s.lastRoute == null)
                {
                    Console.WriteLine("\tEMPTY RUN FROM "+s.parent.sysName+" TO "+s.sysName);
                }
                else
                {
                    Console.WriteLine("\tquantity = " + s.lastQuantityHauled + "; route = " + s.lastRoute.ToString());
                }
                s = s.parent;
            }
        }
 public void nicelyDumpPlanToConsole(PlannerState final)
 {
     Console.WriteLine("TRADE PLAN");
     //reverse the ordering
     List<PlannerState> states = new List<PlannerState>();
     PlannerState s = final;
     while (s.parent != null)
     {
         states.Insert(0, s);
         s = s.parent;
     }
     //print them nicely
     for (int i = 0; i < states.Count; ++i)
     {
         PlannerState si = states[i];
         string header = "[" + (i + 1) + "] " + si.parent.sysName + " --- ";
         string footer = " --> " + si.sysName + " ~ ";
         if (si.lastRoute == null)
         {
             Console.WriteLine(header + "empty" + footer+"1 jump;");
         }
         else
         {
             Console.WriteLine(header + si.lastQuantityHauled + " x " + si.lastRoute.seller.item.name
                 + footer+si.lastRoute.jumps+" jump(s);");
             Console.WriteLine("\t SELL ORDER = " + si.lastRoute.seller);
             Console.WriteLine("\t  BUY ORDER = " + si.lastRoute.buyer);
         }
         Console.WriteLine("\tWallet = "+si.wallet);
     }
 }
 //used to construct an initial state
 public PlannerState(double cargoCapacity, double wallet, string sysName)
 {
     this.cargoCapacity = cargoCapacity;
     this.wallet = wallet;
     this.sysName = sysName;
     this.parent = null;
     this.lastRoute = null;
     this.lastQuantityHauled = 0;
 }
 //used to advance to a new state via a trade route
 public PlannerState(PlannerState previous, TradeRouteMiner.Route routeToTake, int quantityToHaul)
 {
     this.cargoCapacity = previous.cargoCapacity;
     this.wallet = previous.wallet + routeToTake.profitPerItem * quantityToHaul;
     this.jumpsElapsed = previous.jumpsElapsed + jumpElapsedCost(routeToTake.jumps);
     this.sysName = routeToTake.buyer.location.name;
     this.parent = previous;
     this.lastRoute = routeToTake;
     this.lastQuantityHauled = quantityToHaul;
 }
 //used to advance to a new state via an empty jump
 public PlannerState(PlannerState previous, string destination)
 {
     this.cargoCapacity = previous.cargoCapacity;
     this.wallet = previous.wallet;
     this.jumpsElapsed = previous.jumpsElapsed + 1.0;
     this.sysName = destination;
     this.parent = previous;
     this.lastRoute = null;
     this.lastQuantityHauled = 0;
 }
        public PlannerState computePlan(double initialWallet,
            double initialCargoCap,
            string initialSystemName,
            int maxJumps)
        {
            //reset lists
            this.open = new PriorityQueue<double, PlannerState>();
            this.closed = new SpaceTimeProfitCache();

            //compute a heuristic for the max possible profit rate
            double bestProfitRate = 0.0;
            double candidateProfitRate = 0.0;
            foreach(List<TradeRouteMiner.Route> lr in trm.systemRoutes.Values)
            {
                foreach (TradeRouteMiner.Route r in lr)
                {
                    candidateProfitRate = Math.Min(r.profitDensityRate * initialCargoCap, r.bulkProfitRate);
                    bestProfitRate = Math.Max(bestProfitRate, candidateProfitRate);
                }
            }

            //hence we can order PlannerStates by state.wallet + bestProfitRate*(maxJumps-state.jumpsElapsed)
            //and use a*

            Console.WriteLine("best profit rate heuristic : " + bestProfitRate);

            //establish the initial state
            PlannerState initialState = new PlannerState(initialCargoCap, initialWallet, initialSystemName);
            open.push(getPriority(initialState, bestProfitRate, maxJumps), initialState);

            //stat tracking
            int statTouchedStates = 0;
            int statAddedStates = 0;
            int progressUpdateFrequency = 10000;

            //use a* to find the optimal plan up to max specified number of jumps
            while (open.count() > 0)
            {
                PriorityQueue<double, PlannerState>.Pair pair = open.pop();
                ++statTouchedStates;

                //Console.WriteLine("!tradeplanner : open count = " + open.count()
                //    + "; jumpsElapsed = " + pair.value.jumpsElapsed
                //    + "; priority = "+pair.key);

                if (statTouchedStates % progressUpdateFrequency == 0)
                {
                    //display search progress update for user
                    Console.WriteLine("TradePlanner Stats : WORKING");
                    Console.WriteLine("\ttouched states = " + statTouchedStates);
                    Console.WriteLine("\tadded states = " + statAddedStates);
                    Console.WriteLine("\tstates in open list = " + open.count());
                    Console.WriteLine("\thighest priority = " + pair.key);
                    Console.WriteLine("\trecent jumps elapsed = " + pair.value.jumpsElapsed);
                }

                //check for stopping condition
                if (pair.value.jumpsElapsed >= maxJumps)
                {
                    Console.WriteLine("TradePlanner Stats : FINISHED!");
                    Console.WriteLine("\ttouched states = " + statTouchedStates);
                    Console.WriteLine("\tadded states = " + statAddedStates);
                    Console.WriteLine("\tstates in open list = " + open.count());
                    Console.WriteLine("\thighest priority = " + pair.key);
                    Console.WriteLine("\trecent jumps elapsed = " + pair.value.jumpsElapsed);
                    return pair.value;
                }

                //otherwise, expand planner state and pop children back into the open list
                foreach (PlannerState childState in pair.value.expandStates(trm, graph))
                {
                    //only add the child state if it gives us an improved profit upon what we've already seen
                    if(closed.achievesBetterProfit(childState.sysName, childState.jumpsElapsed, childState.wallet))
                    {
                        open.push(getPriority(childState,bestProfitRate, maxJumps), childState);
                        ++statAddedStates;
                    }
                }

            }

            //we've failed, for some reason, to find a plan
            return null;
        }
Exemple #19
0
    public void plan(GameController.WorldState currentWorldState)
    {
        finalPlan = new Stack <PrimitiveTask>();
        Stack <PlannerState> decompHistory = new Stack <PlannerState>();

        GameController.WorldState WorkingWS = currentWorldState.Copy();

        tasksToProcess.Push(new PlayGame());

        while (tasksToProcess.Count > 0)
        {
            Task CurrentTask = tasksToProcess.Pop();
            if (CurrentTask.GetType().IsSubclassOf(typeof(CompoundTask)))
            {
                CompoundTask CurrentCompoundTask = (CompoundTask)CurrentTask;
                Method       SatisfiedMethod     = CurrentCompoundTask.FindSatisfiedMethod(WorkingWS);

                if (SatisfiedMethod != null)
                {
                    //PlannerState currentState = new PlannerState(CurrentCompoundTask, finalPlan, tasksToProcess, SatisfiedMethod);
                    // decompHistory.Push(currentState);
                    SatisfiedMethod.subTasks.Reverse();
                    foreach (Task t in SatisfiedMethod.subTasks)
                    {
                        tasksToProcess.Push(t);
                    }
                    SatisfiedMethod.subTasks.Reverse();
                }
                else if (decompHistory.Count > 0)
                {
                    //RestoreToLastDecomposedTask():
                    PlannerState lastState        = decompHistory.Pop();
                    CompoundTask lastCompoundTask = lastState.currentTask;
                    finalPlan      = lastState.finalPlan;
                    tasksToProcess = lastState.tasksToProcess;
                    // Remove the failed method and return CompoundTask to the stack. On the next iteration, it will be checked again for a valid method.
                    lastCompoundTask.InvalidateMethod(lastState.currentMethod);
                    tasksToProcess.Push(lastCompoundTask);
                }
            }
            else//Primitive Task
            {
                PrimitiveTask CurrentPrimitiveTask = (PrimitiveTask)CurrentTask;
                if (CurrentPrimitiveTask.PrimitiveConditionsMet(WorkingWS))
                {
                    // CurrentPrimitiveTask.ApplyEffects(this, WorkingWS);
                    // Add this PrimitiveTask to the bottom of the finalPlan
                    Stack <PrimitiveTask> temp = new Stack <PrimitiveTask>();
                    for (int i = 0; i < finalPlan.Count; i++)
                    {
                        PrimitiveTask nextTask = finalPlan.Pop();
                        temp.Push(nextTask);
                    }
                    temp.Push(CurrentPrimitiveTask);
                    finalPlan = new Stack <PrimitiveTask>();
                    for (int i = 0; i < temp.Count; i++)
                    {
                        PrimitiveTask nextTask = temp.Pop();
                        finalPlan.Push(nextTask);
                    }
                }
                else if (decompHistory.Count > 0)
                {
                    //RestoreToLastDecomposedTask();
                    PlannerState lastState        = decompHistory.Pop();
                    CompoundTask lastCompoundTask = lastState.currentTask;
                    finalPlan      = lastState.finalPlan;
                    tasksToProcess = lastState.tasksToProcess;
                    // Remove the failed method and return CompoundTask to the stack. On the next iteration, it will be checked again for a valid method.
                    lastCompoundTask.InvalidateMethod(lastState.currentMethod);
                    tasksToProcess.Push(lastCompoundTask);
                }
            }
        }
    }
Exemple #20
0
 public void Add(PlannerState state)
 {
     Heap.Add(state);
     HeapifyUp();
 }
 public double getPriority(PlannerState state, double bestProfitRate, int maxJumps)
 {
     //note here we're implicitly heavily penalising plans that go over max jumps
     return state.wallet + bestProfitRate * (maxJumps - state.jumpsElapsed);
 }
 /// <summary>
 /// Sets the value of the property
 /// </summary>
 /// <param name="state">Current state of the calendar</param>
 private void SetState(PlannerState state)
 {
     _state = state;
 }