Quelle est la différence entre recherche graphique et recherche arborescente versions concernant DFS, A * recherches dans intelligence artificielle?
À en juger par les réponses existantes, il semble y avoir beaucoup de confusion à propos de ce concept.
La distinction entre la recherche par arbre et la recherche par graphe n’est pas liée au fait que le graphe à problème est un graphe ou un graphe général. Il est toujours supposé que vous avez affaire à un graphique général. La distinction réside dans le motif de parcours utilisé pour la recherche dans le graphique, qui peut être en forme de graphique ou en forme d’arbre.
Si vous avez affaire à un problème en forme d'arborescence, les deux variantes de l'algorithme donnent des résultats équivalents. Vous pouvez donc choisir la variante de recherche arborescente la plus simple.
Votre algorithme de base de recherche de graphes ressemble à ce qui suit. Avec un nœud de départ start
, les bords sont dirigés comme successors
et une spécification goal
utilisée dans la condition de boucle. open
contient les nœuds en mémoire, qui sont actuellement à l'étude, le liste ouverte. Notez que le pseudo-code suivant n’est pas correct dans tous les aspects (2).
open <- []
next <- start
while next is not goal {
add all successors of next to open
next <- select one node from open
remove next from open
}
return next
Selon la manière dont vous implémentez select from open
, vous obtenez différentes variantes d’algorithmes de recherche, comme la recherche par profondeur (DFS) (élément le plus récent), la recherche par largeur (BFS) (élément le plus ancien) ou la recherche de coût uniforme (élément de sélection avec le coût de trajet le plus bas), recherche A-star populaire en choisissant le nœud avec la plus basse coût plus heuristique valeur, etc.
L'algorithme indiqué ci-dessus est en fait appelé recherche dans l'arborescence . Il visitera un état du graphe de problème sous-jacent plusieurs fois, s'il existe plusieurs chemins dirigés menant à l'enracinement dans l'état de départ. Il est même possible de visiter un état un nombre infini de fois s'il se trouve sur une boucle dirigée. Mais chaque visite correspond à un noeud différent dans l’arborescence générée par notre algorithme de recherche. Cette apparente inefficacité est parfois recherchée, comme expliqué plus tard.
Comme nous l'avons vu, la recherche dans les arbres peut visiter un état plusieurs fois. Et en tant que tel, il explorera le "sous-arbre" trouvé après cet état plusieurs fois, ce qui peut coûter cher. La recherche de graphique résout ce problème en gardant une trace de tous les états visités dans une liste fermée. Si un successeur nouvellement trouvé de next
est déjà connu, il ne sera pas inséré dans la liste ouverte:
open <- []
closed <- []
next <- start
while next is not goal {
add next to closed
add all successors of next to open, which are not in closed
remove next from open
next <- select from open
}
return next
Nous remarquons que la recherche de graphique nécessite plus de mémoire, car elle garde la trace de tous les états visités. Ceci peut être compensé par la liste ouverte plus petite, ce qui améliore l'efficacité de la recherche.
Certaines méthodes d'implémentation de select
peuvent garantir de renvoyer des solutions optimales - c'est-à-dire un plus court ou un chemin avec coût minimal (pour les graphiques avec coûts attaché aux bords). Ceci est valable lorsque les nœuds sont développés par ordre de coût croissant ou lorsque le coût est une constante positive non nulle. Un algorithme commun qui implémente ce type de sélection est recherche de coût uniforme , ou si les coûts par étape sont identiques, BFS ou [~ ~ ~] iddfs [~ # ~] . IDDFS évite la consommation agressive de mémoire de BFS et est généralement recommandé pour les recherches non informées (force brute) lorsque la taille des étapes est constante.
De plus, l'algorithme de recherche A * tree (très populaire) offre une solution optimale lorsqu'il est utilisé avec une heuristique admissible . L'algorithme de recherche A * graph n'offre toutefois cette garantie que s'il est utilisé avec une heuristique cohérente (ou "monotone") = (une condition plus forte que l'admissibilité).
Pour plus de simplicité, le code présenté ne:
Un arbre est un cas particulier de graphique, donc tout ce qui fonctionne pour les graphiques généraux fonctionne pour les arbres. Un arbre est un graphe où il existe précisément un chemin entre chaque paire de nœuds. Cela implique qu'il ne contient aucun cycle, comme l'indique une réponse précédente, mais un graphe dirigé sans cycles (un DAG, graphe acyclique dirigé) n'est pas nécessairement un arbre.
Toutefois, si vous savez que votre graphique comporte certaines restrictions, par exemple, qu'il s'agisse d'un arbre ou d'un DAG, vous pouvez généralement trouver un algorithme de recherche plus efficace que pour un graphe sans restriction. Par exemple, il n’a probablement aucun sens à utiliser A *, ou son équivalent non-heuristique "algorithme de Dijkstra", sur une arborescence (où il n’existe de toute façon qu'un seul chemin, que vous pouvez trouver par DFS ou BFS) ou sur un DAG (où un chemin optimal peut être trouvé en considérant les sommets dans l'ordre obtenu par le tri topologique).
En ce qui concerne dirigée vs non dirigée, un graphe non orienté est un cas spécial, c'est-à-dire que le cas qui suit la règle "s'il existe un Edge (lien, transition) de u à v il existe également un bord de v à u .
Mise à jour: Notez que si ce qui vous préoccupe est le motif de traversée de la recherche plutôt que la structure du graphe lui-même, Ce n'est pas la réponse. Voir, par exemple, la réponse de @ ziggystar.
La seule différence entre un graphique et un arbre est cycle. Un graphique peut contenir des cycles, pas un arbre. Ainsi, lorsque vous allez implémenter un algorithme de recherche sur une arborescence, vous n'avez pas besoin de considérer l'existence de cycles, mais lorsque vous travaillez avec un graphe arbitraire, vous devez en tenir compte. Si vous ne gérez pas les cycles, l'algorithme peut éventuellement tomber dans une boucle infinie ou une récursion sans fin.
Un autre point à considérer concerne les propriétés directionnelles du graphique auquel vous faites face. Dans la plupart des cas, nous traitons avec des arbres qui représentent les relations parent-enfant à chaque bord. Un DAG (graphe acyclique dirigé) montre également des caractéristiques similaires. Mais les graphiques bidirectionnels sont différents. Chaque bord dans un graphique bidirectionnel représente deux voisins. Les approches algorithmiques devraient donc différer un peu pour ces deux types de graphes.
En termes simples, l’arbre ne contient pas de cycles ni où le graphique le permet. Ainsi, lorsque nous effectuons une recherche, nous devrions éviter les cycles dans les graphiques afin de ne pas entrer dans des boucles infinies.
Un autre aspect est que l’arbre aura typiquement une sorte de tri topologique ou une propriété comme l’arbre de recherche binaire qui rend la recherche si simple et rapide comparée aux graphiques.
GRAPH VS ARBRE
Mais dans le cas d'IA Graph-search vs Tree-search
La recherche de graphes a une bonne propriété. Chaque fois que l'algorithme explore un nouveau nœud et le marque comme visité, "Quel que soit l'algorithme utilisé", l'algorithme explore généralement tous les autres nœuds accessibles depuis le nœud actuel.
Par exemple, considérons le graphe suivant avec 3 sommets A B et C, et considérons ce qui suit les arêtes
A-B, B-C et C-A, il existe un cycle de C à A,
Et quand DFS commençant par A, A générera un nouvel état B, B générera un nouvel état C, mais lorsque C sera exploré, l'algorithme essaiera de générer un nouvel état A mais A sera déjà visité et sera donc ignoré. Cool!
Mais qu'en est-il des arbres? L’algorithme well trees ne marque pas le noeud visité comme visité, mais les arbres n’ont pas de cycles, comment cela se ferait-il dans une boucle infinie?
Considérez cet arbre avec 3 sommets et considérez les arêtes suivantes
A - B - C enraciné en A, vers le bas. Et supposons que nous utilisons l'algorithme DFS
A va générer un nouvel état B, B va générer deux états A & C, car les arbres n'ont pas "Marquer un nœud visité s'il est exploré", donc peut-être que l'algorithme DFS explorera A à nouveau, générant ainsi un nouvel état B, nous entrons dans une boucle infinie.
Mais avez-vous remarqué quelque chose, nous travaillons sur des arêtes non dirigées, c’est-à-dire qu’il existe un lien entre A-B et B-A. bien sûr, ce n'est pas un cycle, car le cycle implique que les sommets doivent être> = 3 et que tous les sommets sont distincts, à l'exception du premier et du dernier nœud.
ST A-> B-> A-> B-> A ce n'est pas un cycle car il enfreint la propriété de cyclage> = 3. Mais effectivement A-> B-> C-> A est un cycle> = 3 nœuds distincts Coché, le premier et le dernier nœud sont identiques.
Encore une fois, considérons les arêtes des arbres, A-> B-> C-> B-> A, bien sûr que ce n'est pas un cycle, car il y a deux Bs, ce qui signifie que tous les nœuds ne sont pas distincts.
Enfin, vous pouvez implémenter un algorithme de recherche arborescente pour éviter d’explorer deux fois le même nœud. Mais cela a des conséquences.