public override List <Board> Solve(EvaluableBoard board) { // Mise en place du seuil à partir du noeud de départ Size = board.Board.Structure.GetLength(0); _destination = Functions.CreateTarget(Size); int threshold = Heuristic.EvaluateBoard(board.Board, _destination.Board); //Setting the StartNode for this iteration EvaluableBoard start = board; while (true) { // Départ de la fonction récursive sur le premier noeud EvaluableBoard temp = Search(start, 0, threshold); int tempScore = temp.Score; if (temp.Equals(_destination)) { openCount = _openSet.Count; closedCount = _closedSet.Count; return(Unpile(temp)); } threshold = tempScore; _openSet = new List <EvaluableBoard>(); _closedSet = new List <EvaluableBoard>(); } }
public bool FindBest(EvaluableBoard board) { bool result = false; foreach (EvaluableBoard currentBoard in _openSet) { if (board.Equals(currentBoard) && currentBoard.Cost <= board.Cost) { result = true; } else if (board.Equals(currentBoard) && currentBoard.Cost > board.Cost) { currentBoard.Cost = board.Cost; } } return(result); }
/// <summary> /// Implémentation de l'algorithme A* /// </summary> /// <param name="board"> tableau de départ à résoudre </param> /// <returns></returns> public override List <Board> Solve(EvaluableBoard board) { // Création de la liste des ouvert vides _openSet = new List <EvaluableBoard>(); int size = board.Size; // taille de l'example à résoudre _destination = Functions.CreateTarget(size); _openSet.Add(board); List <Board> result = new List <Board>(); // Initialisation du chemin // Boucle de résolution while (_openSet.Count > 0) { _currentBoard = _openSet[0]; // On récupère le meilleur élément if (_currentBoard.Equals(_destination)) // Si on est arrivé, on arrête { openCount = _openSet.Count; closedCount = _closedSet.Count; result = Unpile(_currentBoard); return(result); } // Sinon on créer les voisins List <EvaluableBoard> holder = CreateChild(_currentBoard); foreach (EvaluableBoard testBoard in holder) { if (FindPast(testBoard) || FindBest(testBoard)) { } // Si le voisin à déjà été évalué on ne le considère pas else { // On applique les mesure de cout et d'heuristique à l'enfant et on l'ajoute à la liste testBoard.Cost += 1; testBoard.Score = testBoard.Cost + Heuristic.EvaluateBoard(testBoard.Board, _destination.Board); _openSet.Add(testBoard); } } // On enlève le noeud courrant des ouvert et on la joute à l aliste des fermés _closedSet.Add(_currentBoard); _openSet.Remove(_currentBoard); // On ordonne la liste pour garder les meilleurs en premier _openSet = _openSet.OrderBy(b => b.Score).ToList(); } openCount = _openSet.Count; closedCount = _closedSet.Count; return(result); }
/// <summary> /// Fonction récursive au coeur de l'algorithme IDA* /// permet d'évaluer les parcours potentiels vers la solution /// </summary> /// <param name="currEval"></param> /// <param name="cost"></param> /// <param name="threshold"></param> /// <returns></returns> public EvaluableBoard Search(EvaluableBoard currEval, int cost, int threshold) { // Evaluation du cout récursif int f = cost + Heuristic.EvaluateBoard(currEval.Board, _destination.Board); _openSet.Add(currEval); // Si le score dépasse le seuil on coupe la branche if (f > threshold) { currEval.Score = f; return(currEval); } if (currEval.Equals(_destination)) { return(currEval); } int min = int.MaxValue; // Recherche et evaluaiton des voisins List <EvaluableBoard> holder = CreateChild(currEval); foreach (EvaluableBoard child in holder) { child.Score = cost + Heuristic.EvaluateBoard(child.Board, _destination.Board); } holder = holder.OrderBy(b => b.Score).ToList(); foreach (EvaluableBoard child in holder) { _openSet.Remove(currEval); _closedSet.Add(currEval); // Appel récrsif on évalue chaque enfant dans la fonction de recherche EvaluableBoard temp = Search(child, cost + 1, threshold); int tempScore = temp.Score; if (temp.Equals(_destination)) { return(temp); } if (tempScore < min) { min = tempScore; } } currEval.Score = min; return(currEval); }