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

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

Marsh Posté le 27-11-2024 à 15:16:48    

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
Reply

Marsh Posté le 27-11-2024 à 15:16:48   

Reply

Marsh Posté le 27-11-2024 à 16:53:42    

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
Reply

Marsh Posté le 27-11-2024 à 17:02:28    

Merci à Claude pour sa synthèse !

Reply

Marsh Posté le 27-11-2024 à 17:10:18    

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

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed