/*renvoit la distance entre le point correspondant au noeud this et le point correspondant au noeud node*/ public override double GetArcCost(GenericNode node) { //on cherche à quel point ce node (this) correspond parmis les points du monde Point pointNode = Monde.List_Points.Find(point => point.NomPoint == node.GetNom()); if (pointNode != null) { //on cherche à quel point voisin le noeud node correspond lien resultat = pointNode.List_Voisins.Find(voisin => voisin.NomVoisin == node.GetNom()); ; return resultat.Distance; /*if (resultat!=null) { return resultat.distance; } else { string erreur = "ce point n'a pas de voisin correspondant au nom " + node.GetNom(); throw new Exception(erreur); }*/ } else { string erreur = "ce point n'a pas de voisin correspondant au nom " + node.GetNom(); throw new Exception(erreur); } }
public void InsertNewNodeInOpenList(GenericNode NewNode) { // Insertion pour respecter l'ordre du cout total le plus petit au plus grand if (this.L_Ouverts.Count == 0) { L_Ouverts.Add(NewNode); } else { GenericNode N = L_Ouverts[0]; bool trouve = false; int i = 0; do if (NewNode.Cout_Total < N.Cout_Total) { L_Ouverts.Insert(i, NewNode); trouve = true; } else { i++; if (L_Ouverts.Count == i) { N = null; L_Ouverts.Insert(i, NewNode); } else { N = L_Ouverts[i]; } } while ((N != null) && (trouve == false)); } }
public List<GenericNode> RechercheSolutionAEtoile(GenericNode N0) { L_Ouverts = new List<GenericNode>(); L_Fermes = new List<GenericNode>(); // Le noeud passé en paramètre est supposé être le noeud initial GenericNode N = N0; L_Ouverts.Add(N0); // tant que le noeud n'est pas terminal et que ouverts n'est pas vide while (L_Ouverts.Count != 0 && N.EndState() == false) { // Le meilleur noeud des ouverts est supposé placé en tête de liste // On le place dans les fermés L_Ouverts.Remove(N); L_Fermes.Add(N); // Il faut trouver les noeuds successeurs de N this.MAJSuccesseurs(N); // Inutile de retrier car les insertions ont été faites en respectant l'ordre // On prend le meilleur, donc celui en position 0, pour continuer à explorer les états // A condition qu'il existe bien sûr if (L_Ouverts.Count > 0) { N = L_Ouverts[0]; } else { N = null; } } // A* terminé // On retourne le chemin qui va du noeud initial au noeud final sous forme de liste // Le chemin est retrouvé en partant du noeud final et en accédant aux parents de manière // itérative jusqu'à ce qu'on tombe sur le noeud initial List<GenericNode> _LN = new List<GenericNode>(); if (N != null) { _LN.Add(N); while (N != N0) { N = N.GetNoeud_Parent(); _LN.Insert(0, N); // On insère en position 1 } } return _LN; }
// Méthodes abstraites, donc à surcharger obligatoirement avec override dans une classe fille public abstract double GetArcCost(GenericNode N2);
public void SetNoeud_Parent(GenericNode g) { ParentNode = g; g.Enfants.Add(this); }
protected List <GenericNode> Enfants; // noeuds enfants public GenericNode(string nom) { Name = nom; ParentNode = null; Enfants = new List <GenericNode>(); }
private void MAJSuccesseurs(GenericNode N) { // On fait appel à GetListSucc, méthode abstraite qu'on doit réécrire pour chaque // problème. Elle doit retourner la liste complète des noeuds successeurs de N. List<GenericNode> listsucc = N.GetListSucc(); foreach (GenericNode N2 in listsucc) { // N2 est-il une copie d'un nœud déjà vu et placé dans la liste des fermés ? GenericNode N2bis = ChercheNodeDansFermes(N2.GetNom()); if (N2bis == null) { // Rien dans les fermés. Est-il dans les ouverts ? N2bis = ChercheNodeDansOuverts(N2.GetNom()); if (N2bis != null) { // Il existe, donc on l'a déjà vu, N2 n'est qu'une copie de N2Bis // Le nouveau chemin passant par N est-il meilleur ? if (N.GetGCost() + N.GetArcCost(N2) < N2bis.GetGCost()) { // Mise à jour de N2bis N2bis.SetGCost(N.GetGCost() + N.GetArcCost(N2)); // HCost pas recalculé car toujours bon N2bis.calculCoutTotal(); // somme de GCost et HCost // Mise à jour de la famille .... N2bis.Supprime_Liens_Parent (); N2bis.SetNoeud_Parent(N); // Mise à jour des ouverts L_Ouverts.Remove(N2bis); this.InsertNewNodeInOpenList(N2bis); } // else on ne fait rien, car le nouveau chemin est moins bon } else { // N2 est nouveau, MAJ et insertion dans les ouverts N2.SetGCost(N.GetGCost() + N.GetArcCost(N2)); N2.CalculeHCost(); N2.SetNoeud_Parent(N); N2.calculCoutTotal(); // somme de GCost et HCost this.InsertNewNodeInOpenList(N2); } } // else il est dans les fermés donc on ne fait rien, // car on a déjà trouvé le plus court chemin pour aller en N2 } }
// Méthodes abstrates, donc à surcharger obligatoirement avec override dans une classe fille public abstract double GetArcCost(GenericNode N2);
public void Supprime_Liens_Parent() { if (ParentNode == null) return; ParentNode.Enfants.Remove(this); ParentNode = null; }
public override double GetArcCost(GenericNode N2) { return(1); }
private void btn_valider_Click(object sender, EventArgs e) // Methode pour bouton Calcul { if (objChoisi != null & charChoisi != null) { objet = new Objet(objChoisi.posX - 1, objChoisi.posY - 1, objChoisi.orientation, objChoisi.hauteur);//On définit l'objet avec les valeurs récupérés dans l'éditText (objet choisi) g = new Graph(objet); if (sender.Equals(btn_calcul_distance)) //Si on clique sur le bouton calcul distance { Ninit = new NodeDistance(charChoisi.posX - 1, charChoisi.posY - 1); // On définit la position du chariot choisi comme la position Initiale d'un Noeud distance nodeTemps = false; } else if (sender.Equals(btn_calcul_temps)) { Ninit = new NodeTemps(charChoisi.posX - 1, charChoisi.posY - 1, new Point(0, 0)); nodeTemps = true; } Lres = g.RechercheSolutionAEtoile(Ninit); //On calcule la liste des noeuds répondant à la distance la plus courte ou au temps le plus court if (nodeTemps) // Nobj sera un nodeTemps, on va chercher à avoir le cout en temps { // Trajet vers la zone finale Nobj = (NodeTemps)Lres[Lres.Count - 1]; //Noeud sur lequel est le chariot lorsqu'il prend l'objet } else//Nobj sera un nodeDistance, on va chercher à avoir le cout en distance { Nobj = (NodeDistance)Lres[Lres.Count - 1]; //Noeud sur lequel est le chariot lorsqu'il prend l'objet } List <Objet> zoneFinale = new List <Objet>(tabEntrepot.GetLength(0)); for (int k = 0; k < tabEntrepot.GetLength(0) - 1; k++) { Objet o = new Objet(0, k - 1, Objet.Orientation.Sud, 0); //On imagine un objet correspondant à la ligne 1. zoneFinale.Add(o); //On ajoute à la liste des zones finales. } foreach (Objet o in zoneFinale) { Graph g = new Graph(o); TrajectoireF = g.RechercheSolutionAEtoile(Nobj); //On stocke la liste de noeuds correspondant à chaque chemin pour aller vers une des zones finales et on le stocke dans la liste EnsembleTrajectoiresF.Add(TrajectoireF); //On ajoute cette trajectoire à l'ensemble des trajectoires } bestTrajectoire = EnsembleTrajectoiresF[0]; double cout = 1000000; foreach (List <GenericNode> l in EnsembleTrajectoiresF) { double c = l[l.Count - 1].Cout_Total;// Pour chaque liste de chemins dans l'ensemble des trajectoires, on récupère le cout total. if (c < cout) { cout = c; bestTrajectoire = l;//On garde la trajectoire où le cout est le plus faible } } if (nodeTemps) { lbTimeTot.Text = CalculTempsTot().ToString() + " secondes";// On appelle la méthode pour calculer le temps et on l'affiche dans un label. } if (Lres.Count > 1) { Lres.RemoveAt(0); //On supprime le premier noeud correspondant à la position du chariot } reinitialiserView(); // On reinitialise la View setViewEntrepot(); // On dessine la grille } else { label_error.Visible = true; } }
//Methodes public override bool IsEqual(GenericNode N2) { Emplacement E1 = (Emplacement)(N2); return(E1.x == this.x && E1.y == this.y && E1.orientation == this.orientation); }
public override double GetArcCost(GenericNode N2) { return (1); }
public override double GetArcCost(GenericNode N2) { Emplacement_Q3 succ = (Emplacement_Q3)N2; //return (1); if (EndState(succ)) { return(4 * hauteurColis + 10); } else { if (orientation == "Nord") { if (succ.y == this.y - 1) { return(1); } else { return(4); } } else if (orientation == "Sud") { if (succ.y == this.y + 1) { return(1); } else { return(4); } } else if (orientation == "Est") { if (succ.x == this.x + 1) { return(1); } else { return(4); } } else if (orientation == "Ouest") { if (succ.x == this.x - 1) { return(1); } else { return(4); } } else { return(0); } } }
public override bool IsEqual(GenericNode N2) // Permet de verifier si deux noeuds sont égaux. ??? { NodeBateau NT = (NodeBateau)(N2); // Permet la conversion N2 qui est un Genericcode en NodeBateau, il force la conversion return(NT._x == _x && NT._y == _y); // Verifier si les x et y sont égaux, ça retourne true ou false ce test d'égalité }
public override bool IsEqual(GenericNode N2) { NodeDistance NE = (NodeDistance)N2; return(NE.posX == posX && NE.posY == posY); }
public override bool IsEqual(GenericNode N2) { NodeTaquin NT = (NodeTaquin)(N2); return(NT.Name == Name); }
protected List <GenericNode> Enfants; // noeuds enfants public GenericNode() { ParentNode = null; Enfants = new List <GenericNode>(); }
public override bool IsEqual(GenericNode N2) // Cette fonction renvoie un booleen : permet de verifier si deux noeuds sont égaux { NodeBateau NT = (NodeBateau)(N2); // Permet la conversion N2 qui est un Genericcode en NodeBateau return(NT._x == _x && NT._y == _y); // Verifier si les x et y sont égaux, ça retourne true ou false }
// Méthodes abstrates, donc à surcharger obligatoirement avec override dans une classe fille public abstract bool IsEqual(GenericNode N2);
protected double TotalCost; //coût total (g+h) #endregion Fields #region Constructors public GenericNode(string nom) { Name = nom; ParentNode = null; Enfants = new List<GenericNode>(); }
public abstract double GetArcCost(GenericNode N2); // ajouter les windspeed
// AjouteBranche est exclusivement appelée par GetSearchTree; les noeuds sont ajoutés de manière récursive private void AjouteBranche( GenericNode GN, TreeNode TN) { foreach (GenericNode GNfils in GN.GetEnfants()) { TreeNode TNfils = new TreeNode(GNfils.GetNom()); TN.Nodes.Add(TNfils); if (GNfils.GetEnfants().Count > 0) AjouteBranche(GNfils, TNfils); } }