Пример #1
0
        /// <summary>
        /// Check if the move is valid, i.e. not colliding into walls or other agents.
        /// </summary>
        /// <param name="possibleMove">The proposed move (to check if it is valid)</param>
        /// <param name="agentNum">The index of the agent that is proposed to perform the move</param>
        /// <param name="previousAgentMoves">A collection of moves that will be done by the other agents</param>
        /// <returns></returns>
        private bool IsValid(Move possibleMove, int agentNum, ICollection <Move> previousAgentMoves)
        {
            // If the tile is not free (out of the grid or with an obstacle)
            if (m_Problem.IsValid(possibleMove) == false)
            {
                return(false);
            }

            // If previous move of another agent will collide with this move
            if (previousAgentMoves.Contains(possibleMove) || previousAgentMoves.Contains(possibleMove.GetOppositeMove()))
            {
                return(false);
            }
            return(true);
        }
Пример #2
0
        private void Generate
        (
            MAM_AgentState node,
            MAM_AgentState child
        )
        {
            if (expandedNodes.Contains(child))
            {
                return;
            }
            Move childMove = child.lastMove;

            if (!instance.IsValid(childMove))                               // Not a valid location
            {
                return;
            }
            if (!closed(child))
            {
                if (child.f >= getBestCost())
                {
                    return;
                }
                child.numOfAgentsInBestHeuristic = instance.m_vAgents.Length;
                if (openList.Contains(child))
                {
                    child.h          = ((MAM_AgentState)openList.Get(child)).h;
                    child.heuristics = ((MAM_AgentState)openList.Get(child)).heuristics;
                }
                else
                {
                    CalculateH(child, node);
                }
                CalculateF(child);
                openList.Add(child);
                UpdateBestCost(child);
                nodesGenerated++;
            }
        }
Пример #3
0
        /// <summary>
        /// Generates a problem instance based on a DAO map file.
        /// TODO: Fix code dup with GenerateProblemInstance and Import later.
        /// </summary>
        /// <param name="agentsNum"></param>
        /// <returns></returns>
        public ProblemInstance GenerateDragonAgeProblemInstance(string mapFileName, int agentsNum)
        {
            /**
             * Randomization based on timer is disabled for purposes of getting
             * reproducible experiments.
             */
            //Random rand = new Random();

            m_mapFileName = mapFileName;
            m_agentNum    = agentsNum;
            TextReader input = new StreamReader(mapFileName);

            string[] lineParts;
            string   line;

            line = input.ReadLine();
            Debug.Assert(line.StartsWith("type octile"));

            // Read grid dimensions
            line      = input.ReadLine();
            lineParts = line.Split(' ');
            Debug.Assert(lineParts[0].StartsWith("height"));
            int maxX = int.Parse(lineParts[1]);

            line      = input.ReadLine();
            lineParts = line.Split(' ');
            Debug.Assert(lineParts[0].StartsWith("width"));
            int maxY = int.Parse(lineParts[1]);

            line = input.ReadLine();
            Debug.Assert(line.StartsWith("map"));
            bool[][] grid = new bool[maxX][];
            char     cell;

            for (int i = 0; i < maxX; i++)
            {
                grid[i] = new bool[maxY];
                line    = input.ReadLine();
                for (int j = 0; j < maxY; j++)
                {
                    cell = line.ElementAt(j);
                    if (cell == '@' || cell == 'O' || cell == 'T' || cell == 'W' /* Water isn't traversable from land */)
                    {
                        grid[i][j] = true;
                    }
                    else
                    {
                        grid[i][j] = false;
                    }
                }
            }

            int x;
            int y;

            Agent[]      agentGoals  = new Agent[agentsNum];
            AgentState[] agentStates = new AgentState[agentsNum];
            bool[][]     goals       = new bool[maxX][];

            for (int i = 0; i < maxX; i++)
            {
                goals[i] = new bool[maxY];
            }

            // Choose random valid unclaimed goal locations
            for (int i = 0; i < agentsNum; i++)
            {
                x = rand.Next(maxX);
                y = rand.Next(maxY);
                if (goals[x][y] || grid[x][y])
                {
                    i--;
                }
                else
                {
                    goals[x][y]   = true;
                    agentGoals[i] = new Agent(x, y, i);
                }
            }

            // Select random start/goal locations for every agent by performing a random walk
            for (int i = 0; i < agentsNum; i++)
            {
                agentStates[i] = new AgentState(agentGoals[i].Goal.x, agentGoals[i].Goal.y, agentGoals[i]);
            }

            ProblemInstance problem = new ProblemInstance();

            problem.parameters[ProblemInstance.GRID_NAME_KEY] = Path.GetFileNameWithoutExtension(mapFileName);
            problem.Init(agentStates, grid);

            for (int j = 0; j < RANDOM_WALK_STEPS; j++)
            {
                for (int i = 0; i < agentsNum; i++)
                {
                    goals[agentStates[i].lastMove.x][agentStates[i].lastMove.y] = false; // We're going to move the goal somewhere else
                    // Move in a random legal direction:
                    while (true)
                    {
                        Move.Direction op = (Move.Direction)rand.Next(0, 5); // TODO: fixme
                        agentStates[i].lastMove.Update(op);
                        if (problem.IsValid(agentStates[i].lastMove) &&
                            !goals[agentStates[i].lastMove.x][agentStates[i].lastMove.y]) // This spot isn't another agent's goal
                        {
                            break;
                        }
                        else
                        {
                            agentStates[i].lastMove.setOppositeMove(); // Rollback
                        }
                    }
                    goals[agentStates[i].lastMove.x][agentStates[i].lastMove.y] = true; // Claim agent's new goal
                }
            }

            // Zero the agents' timesteps
            foreach (AgentState agentStart in agentStates)
            {
                agentStart.lastMove.time = 0;
            }

            return(problem);
        }
Пример #4
0
        /// <summary>
        /// Generates a problem instance, including a board, start and goal locations of desired number of agents
        /// and desired precentage of obstacles
        /// TODO: Refactor to use operators.
        /// </summary>
        /// <param name="gridSize"></param>
        /// <param name="agentsNum"></param>
        /// <param name="obstaclesNum"></param>
        /// <returns></returns>
        public ProblemInstance GenerateProblemInstance(int gridSize, int agentsNum, int obstaclesNum)
        {
            m_mapFileName = "GRID" + gridSize + "X" + gridSize;
            m_agentNum    = agentsNum;

            /**
             * Randomization based on timer is disabled for purposes of getting
             * reproducible experiments.
             */
            //Random rand = new Random();

            if (agentsNum + obstaclesNum + 1 > gridSize * gridSize)
            {
                throw new Exception("Not enough room for " + agentsNum + ", " + obstaclesNum + " and one empty space in a " + gridSize + "x" + gridSize + "map.");
            }

            int x;
            int y;

            Agent[]      aGoals = new Agent[agentsNum];
            AgentState[] aStart = new AgentState[agentsNum];
            bool[][]     grid   = new bool[gridSize][];
            bool[][]     goals  = new bool[gridSize][];

            // Generate a random grid
            for (int i = 0; i < gridSize; i++)
            {
                grid[i]  = new bool[gridSize];
                goals[i] = new bool[gridSize];
            }
            for (int i = 0; i < obstaclesNum; i++)
            {
                x = rand.Next(gridSize);
                y = rand.Next(gridSize);
                if (grid[x][y]) // Already an obstacle
                {
                    i--;
                }
                grid[x][y] = true;
            }

            // Choose random goal locations
            for (int i = 0; i < agentsNum; i++)
            {
                x = rand.Next(gridSize);
                y = rand.Next(gridSize);
                if (goals[x][y] || grid[x][y])
                {
                    i--;
                }
                else
                {
                    goals[x][y] = true;
                    aGoals[i]   = new Agent(x, y, i);
                }
            }

            // Select random start/goal locations for every agent by performing a random walk
            for (int i = 0; i < agentsNum; i++)
            {
                aStart[i] = new AgentState(aGoals[i].Goal.x, aGoals[i].Goal.y, aGoals[i]);
            }

            // Initialized here only for the IsValid() call. TODO: Think how this can be sidestepped elegantly.
            ProblemInstance problem = new ProblemInstance();

            problem.Init(aStart, grid);

            for (int j = 0; j < RANDOM_WALK_STEPS; j++)
            {
                for (int i = 0; i < agentsNum; i++)
                {
                    goals[aStart[i].lastMove.x][aStart[i].lastMove.y] = false; // We're going to move the goal somewhere else
                    while (true)
                    {
                        Move.Direction op = (Move.Direction)rand.Next(0, 5); // TODO: fixme
                        aStart[i].lastMove.Update(op);
                        if (problem.IsValid(aStart[i].lastMove) &&
                            !goals[aStart[i].lastMove.x][aStart[i].lastMove.y]) // this spot isn't another agent's goal
                        {
                            break;
                        }
                        else
                        {
                            aStart[i].lastMove.setOppositeMove(); // Rollback
                        }
                    }
                    goals[aStart[i].lastMove.x][aStart[i].lastMove.y] = true; // Claim agent's new goal
                }
            }

            // Zero the agents' timesteps
            foreach (AgentState agentStart in aStart)
            {
                agentStart.lastMove.time = 0;
            }

            // TODO: There is some repetition here of previous instantiation of ProblemInstance. Think how to elegantly bypass this.
            problem = new ProblemInstance();
            problem.Init(aStart, grid);
            return(problem);
        }