コード例 #1
0
        private int findDist(UniverseGraph.SystemId source, UniverseGraph.SystemId dest)
        {
            open = new PriorityQueue<int, Node>();
            closed = new HashSet<UniverseGraph.SystemId>();

            open.push(0, new Node(null, source));

            Node current = null;
            int currentPriority = 0;
            while ((open.count() > 0) && (closed.Count < maxClosedSize))
            {
                //pop top
                PriorityQueue<int, Node>.Pair head = open.pop();
                current = head.value;
                currentPriority = head.key;

                //check if we've reached the destination
                if (current.sysid.id == dest.id)
                    return currentPriority*-1;

                if (!closed.Contains(current.sysid))
                {
                    //mark that we've already expanded it
                    closed.Add(current.sysid);
                    //expand it
                    foreach (UniverseGraph.SystemId neighbour in graph.systemEdges[current.sysid])
                    {
                        if (graph.idToInfo[neighbour].security > minSecurity)
                        {
                            Node nNode = new Node(current, neighbour);
                            //decrease priority by number of jumps so far - ie breadth first search
                            //some a* like heuristic would be nice....
                            int nPriority = currentPriority - 1;
                            open.push(nPriority, nNode);
                        }
                    }
                }
            }

            //some kind of failure state - either no path, or seach size exceeded (too far)
            return -1;
        }
コード例 #2
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;
        }