/// <summary> /// Returns all the children of a given MDD node that have a heuristic estimate that is not larger than the given heuristic bound. /// </summary> /// <param name="mdd"></param> /// <param name="heuristicBound">The heuristic estimate of the returned children must be lower than or equal to the bound</param> /// <param name="numOfAgents">The number of agents in the MDD node</param> /// <returns>A list of relevant MDD nodes</returns> private List <MDDNode> GetAllChildren(MDDNode father, int heuristicBound, int numOfAgents) { var children = new List <MDDNode>(); foreach (TimedMove move in father.move.GetNextMoves()) { if (this.problem.IsValid(move) && this.problem.GetSingleAgentOptimalCost(this.agentNum, move) <= heuristicBound) // Only nodes that can reach the goal in the given cost according to the heuristic. { if (this.constraints != null) { queryConstraint.Init(agentNum, move); if (this.constraints.Contains(queryConstraint)) { continue; } } if (this.mustConstraints != null && move.time < this.mustConstraints.Length && // There may be a constraint on the timestep of the generated node this.mustConstraints[move.time] != null && this.mustConstraints[move.time].ContainsKey(this.agentNum)) // This agent has a must constraint for this time step { if (this.mustConstraints[move.time][this.agentNum].Equals(move) == false) { continue; } } MDDNode child = new MDDNode(move, numOfAgents, this, this.supportPruning); children.Add(child); } } return(children); }
/// <summary> /// Check if the move is valid, i.e. not colliding into walls or other agents. /// This method is here instead of in ProblemInstance to enable algorithmic tweaks. /// </summary> /// <param name="possibleMove">The move to check if possible</param> /// <returns>true, if the move is possible.</returns> protected bool IsValid(TimedMove possibleMove, HashSet <TimedMove> currentMoves, int makespan, int agentNum) { // Check if the proposed move is reserved in the plan of another agent. // This is used in Trevor's IndependenceDetection. if (this.illegalMoves != null) { if (possibleMove.IsColliding(illegalMoves)) { return(false); } } // FIXME: Also checked in instance.IsValid later. if (this.constraintList != null) { queryConstraint.Init(agentNum, possibleMove); if (this.constraintList.Contains(queryConstraint)) { return(false); } } if (this.mustConstraints != null && makespan < this.mustConstraints.Length && // There may be a constraint on the timestep of the generated node this.mustConstraints[makespan] != null) { if (this.mustConstraints[makespan].Any <CbsConstraint>( con => con.ViolatesMustConstraint((byte)agentNum, possibleMove))) { return(false); } } // If the tile is not free (out of the grid or with an obstacle) if (this.instance.IsValid(possibleMove) == false) { return(false); } // Check against all the agents that have already moved to see if current move collides with their move return(possibleMove.IsColliding(currentMoves) == false); }