Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1752 connectés 

  FORUM HardWare.fr
  Programmation
  Ada

  [Ada] A* (path finding) implémentation incorrect

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[Ada] A* (path finding) implémentation incorrect

n°2485690
lady287
Posté le 27-11-2024 à 15:16:48  profilanswer
 

Bonjour,
 
J'ai réimplementé Astar mais mon code est incorrecte.
 
Si vous pouviez me donner un coup de main.
 
S'il vous plait ?
 
Voici mon code sources Ada :
 

Code :
  1. procedure Astar (Open : in Element_List;
  2.                Close  : out Element_List) is
  3.     
  4.     
  5.     
  6.      Openned : Node_List;    
  7.      Closed : Node_List;
  8.     
  9.      Openned_Curs : Node_Lists.Cursor;
  10.      Close_Curs : Element_Lists.Cursor;
  11.     
  12.      Done : Boolean := False;
  13.     
  14.      Initial_Node : Node_Record;
  15.      Goal : Element;
  16.      Node : Node_Record;
  17.      begin
  18.      Goal := Element_Lists.Last_Element(Open);
  19.      Close_Curs := Element_Lists.First(Open);
  20.      Adjust(Initial_Node, Element_Lists.First_Element(Open));    
  21.      Node_Lists.Append(Openned, Initial_Node);
  22.     Astar_Loop :
  23.      while not Is_Empty(Openned) loop
  24.         Nodes_Sorting.Sort(Openned);
  25.         declare
  26.            Openned_Find_Curs : Node_Lists.Cursor :=
  27.          Node_Lists.First(Openned);
  28.            Best_Node : Node_Record;
  29.            F : Float := 0.0;       --            successor.f = successor.g + successor.h
  30.         begin
  31.            Best_Node := Node_Lists.Element(Openned_Find_Curs);
  32.            Best_Node.Ucost := Uniform(Best_Node.E);
  33.            Best_Node.Hcost := Heuristic(Best_Node.E);
  34.            Node_Lists.Delete_First(Openned);
  35.            --Text_Io.Put_Line("New successors :" );
  36.            declare
  37.           Best_Successors : El_Array := Successors(Best_Node.E);
  38.           
  39.           
  40.           
  41.           
  42.            begin
  43.           --Text_Io.Put_Line("Nb successors : " & Integer'Image(Best_Successors'Length));
  44.           for Succ in Best_Successors ' range loop
  45.              declare
  46.             E : Element := Best_Successors(Succ);
  47.              begin
  48.             --Text_Io.Put_Line("Successor " & Integer'Image(Succ) & " : " );
  49.             if Equal(E, Goal) then --          i) if successor is the goal, stop search
  50.                Adjust(Node, E);
  51.                Node_Lists.Append(Closed, Node);
  52.                exit Astar_Loop;              
  53.             else
  54.                Adjust(Node, E);
  55.                --          ii) else, compute both g and h for successor
  56.                --            successor.g = q.g + distance between
  57.                --                                successor and q              
  58.                Node.Ucost :=  Best_Node.ucost + uniform(Node.E);
  59.               
  60.                --            successor.h = distance from goal to
  61.                --            successor (This can be done using many
  62.                --Text_Io.Put_Line("             - ucost = " & float'Image(Node.Ucost));
  63.                Node.Hcost := Heuristic(Goal) - Heuristic(Node.E);
  64.                --Text_Io.Put_Line("             - hcost = " & float'Image(Node.Hcost));
  65.               
  66.                --            successor.f = successor.g + successor.h
  67.                F := Node.Ucost + Node.Hcost;
  68.                --Text_Io.Put_Line("             - F = " & float'Image(F));
  69.                declare
  70.                   
  71.                begin
  72.                   
  73.                   if not Node_Lists.Is_Empty(Openned) then
  74.                  declare
  75.                     Open_curs : Node_Lists.Cursor := Node_Lists.First(Openned);
  76.                     
  77.                  begin
  78.                     for Open in 1..Node_Lists.Length(Closed) loop
  79.                        declare
  80.                       Open_Node : Node_Record;
  81.                        begin
  82.                       Open_Node := Node_Lists.First_Element(Openned);
  83.                       if Equal(Open_Node.E, Node.E) and then
  84.                         (Open_Node.Ucost + Open_Node.Hcost) < F then
  85.                          Done := True;
  86.                       end if;
  87.                        end;
  88.                        exit when Open = Node_Lists.Length(Openned);
  89.                        Open_Curs := Node_Lists.Next(Open_Curs);
  90.                     end loop;
  91.                  end;
  92.                  if not Done then
  93.                     if not Node_Lists.Is_Empty(Closed) then
  94.                        declare
  95.                       Close_curs : Node_Lists.Cursor := Node_Lists.First(Closed);
  96.                        begin
  97.                       for close in 1..Node_Lists.Length(Closed) loop
  98.                          declare
  99.                         Close_Node : Node_Record := Node_Lists.Element(Close_Curs);
  100.                          begin
  101.                         if Equal(Close_Node.E, Goal) and then
  102.                           (Close_Node.Ucost + Close_Node.Hcost) < F then
  103.                            Done := True;
  104.                         end if;
  105.                          end;
  106.                          exit when Close = Node_Lists.Length(Closed);
  107.                          Close_Curs := Node_Lists.Next(Close_Curs);
  108.                       end loop;
  109.                        end;
  110.                     end if;
  111.                  end if;
  112.                  if not Done then
  113.                     
  114.                     --Text_Io.Put_Line("Adding new node in openned" );
  115.                     
  116.                     Node_Lists.Append(Openned, Node);
  117.                  end if;
  118.                  Done := False;
  119.                   end if;
  120.                end;
  121.             end if;
  122.              end;            
  123.           end loop;
  124.           --Text_Io.Put_Line("Adding new node in closed" ); --      e) push q on the closed list
  125.           Node_Lists.Append(Closed, Best_Node);
  126.           
  127.            end;
  128.         end;
  129.         
  130.         
  131.      end loop Astar_Loop;
  132.     
  133.      Openned_Finalization(Close, Closed);
  134.      --Element_Lists.Reverse_Elements(Close);
  135.     
  136.      end Astar;


 
J'ai peut-être inversé open et close malgrès moi, mais normalement le code est cohérent.
 
J'ai un doute sur les ligne de 91 à 119


Message édité par lady287 le 27-11-2024 à 15:22:26
mood
Publicité
Posté le 27-11-2024 à 15:16:48  profilanswer
 

n°2485691
mechkurt
Posté le 27-11-2024 à 16:53:42  profilanswer
 

Citation :

Je n'y connais rien en ADA mais j'ai demandé à https://claude.ai/ s'il pouvait t'aider :


Je vais examiner attentivement votre implémentation de l'algorithme A* en Ada. Vous avez raison de douter des lignes 91 à 119, car c'est effectivement une partie critique de l'algorithme où plusieurs vérifications sont effectuées.
Quelques observations et suggestions :
 
Structure générale de l'algorithme :
 
Votre implémentation suit globalement la logique de base de A* :
 
Initialisation des listes Openned et Closed
Parcours des successeurs
Calcul des coûts (g, h, f)
Vérification des conditions pour ajouter ou non un nœud
 
Points potentiellement problématiques (lignes 91-119) :

Code :
  1. if not Node_Lists.Is_Empty(Openned) then
  2.    declare
  3.       Open_curs : Node_Lists.Cursor := Node_Lists.First(Openned);
  4.      
  5.    begin
  6.       for Open in 1..Node_Lists.Length(Closed) loop
  7.          declare
  8.             Open_Node : Node_Record;
  9.          begin
  10.             Open_Node := Node_Lists.First_Element(Openned);
  11.             if Equal(Open_Node.E, Node.E) and then
  12.                (Open_Node.Ucost + Open_Node.Hcost) < F then
  13.                Done := True;
  14.             end if;
  15.          end;
  16.          exit when Open = Node_Lists.Length(Openned);
  17.          Open_Curs := Node_Lists.Next(Open_Curs);
  18.       end loop;
  19.    end;


Problèmes dans ce bloc :
 
La boucle parcourt Node_Lists.Length(Closed) mais utilise First_Element(Openned), ce qui semble incohérent
La condition de sortie et l'incrémentation du curseur ne semblent pas correctes
La logique de vérification des nœuds existants est confuse
 
Suggestion de refactorisation :

Code :
  1. -- Vérifier si un chemin plus court existe déjà dans Openned
  2. if not Node_Lists.Is_Empty(Openned) then
  3.    declare
  4.       Open_Curs : Node_Lists.Cursor := Node_Lists.First(Openned);
  5.    begin
  6.       while Node_Lists.Has_Element(Open_Curs) loop
  7.          declare
  8.             Open_Node : Node_Record := Node_Lists.Element(Open_Curs);
  9.          begin
  10.             -- Vérifier si un nœud équivalent existe avec un coût inférieur
  11.             if Equal(Open_Node.E, Node.E) and then
  12.                (Open_Node.Ucost + Open_Node.Hcost) < F then
  13.                Done := True;
  14.                exit;
  15.             end if;
  16.          end;
  17.          Open_Curs := Node_Lists.Next(Open_Curs);
  18.       end loop;
  19.    end;
  20. end if;


Modifications proposées :
 
Utiliser une boucle while avec Has_Element
Utiliser Element au lieu de First_Element
Simplifier la logique de parcours et de comparaison
 
Recommandations générales :
 
Assurez-vous que vos types Node_Record, Element, et les fonctions Equal, Uniform, Heuristic, et Successors sont correctement définis
Vérifiez la cohérence des types de données et des conversions
Les commentaires indiquent que vous gérez bien les étapes clés de A* : calcul de g, h, f, et gestion des successeurs
 
Voulez-vous que je vous aide à affiner cette partie du code ? Je peux vous guider étape par étape pour améliorer l'implémentation de votre algorithme A*.

Citation :

Tu peux créer un compte gratuitement pour faire quelques requêtes chaque jour...


---------------
D3
n°2485692
lady287
Posté le 27-11-2024 à 17:02:28  profilanswer
 

Merci à Claude pour sa synthèse !

n°2485693
lady287
Posté le 27-11-2024 à 17:10:18  profilanswer
 

En effet, une correction à apporter est d'utiliser Element à l'instar de First_Element ligne 82.


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Ada

  [Ada] A* (path finding) implémentation incorrect

 

Sujets relatifs
[Ada][per cent] calcul du pourcenage[Ada][computerman/Skywalker]Outil de développement pour le langage Ada
[Powershell] Résultat RegExp incorrect (bug?)[Ada][Adacore] Problème d'édition de lien avec GPS
erreur de compilation caractère incorrect[Ada] Ecrire un programme de gestion de valeur en ligne de commande
Clip-path mouse follow[STM32]Implémentation afficheur oled NHD0420CW en I²C
[Divers/Ada] décire la structure du programme pour présenter un index[Ada][cybernetic] intégrer le système : approche neurale du problème.
Plus de sujets relatifs à : [Ada] A* (path finding) implémentation incorrect


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR