Ich versuche, DFS-Baum mit rekursiven Algorithmus zu erstellen.Gibt es eine Möglichkeit, statische Daten in Haskell darzustellen? Oder gibt es einen anderen eleganten Algorithmus für das DFS-Traversal in Haskell?
Pseudo-Code hierfür lautet:
DFF(G)
Mark all nodes u as unvisited
while there is an unvisited node u do
DFS(u)
.
DFS(u)
Mark u as visited
for each v in u's neighbor do
if v is not marked
DFS(v)
Während ich kann ziemlich leicht dies in einfacher Weise in imperativen Sprache zu erreichen, indem eine Art von Datenstruktur für un/besuchten Knoten konstruieren, so dass sie die dynamische Zuordnung oder irgendeine Art von Erklärung, für Haskell zuweisen, es ist unmöglich, tun Sie es, weil Haskells Reinheit mich daran hindert, Daten zu ändern, während ich Parameter übergebe.
data Graph a = Graph [(a,[a])] deriving (Ord, Eq, Show)
data Tree a = Node a [Tree a] deriving (Ord, Eq, Show)
type Point = (Int, Int)
type Edges = [Point]
type Path = [Point]
pathGraphFy :: Graph Point -> Point -> Tree (Point,Path)
pathGraphFy inputGraph point = getPathVertex inputGraph (point,[])
getPathVertex :: Graph Point -> (Point, Path) -> Tree (Point,Path)
getPathVertex inputGraph (point,path) =
Node (point,point:path) (map (getPathVertex inputGraph) [(x,(point:path)) | x<- neighbors, x `notElem` path])
where neighbors = pointNeighbor inputGraph point
pointNeighbor :: Graph Point -> Point -> Edges
pointNeighbor (Graph (x:xs)) point =
if fst x == point then snd x else pointNeighbor (Graph(xs)) point
Dies ist, was ich für Graph Traversal mit der DFS-ish (oder eher BFS-ish) Algorithmus haben aber das Problem ist, dass es wieder alle Punkte besuchen in den Punkten Weg ist das nicht. (dh wenn es einen Zyklus gibt, wird er auf beide Arten im Uhrzeigersinn und gegen den Uhrzeigersinn verfahren)
Ich habe auch versucht, einen anderen Graph mit besuchten Punkten zu currying, da Graphs passed by parameters nur Daten von Graph im Traversal enthält ((dh ist nicht global)
Wenn nur dynamische Zuordnung oder statische Daten zu Daten für globale Ebene möglich war, kann dies leicht gelöst werden, aber ich bin etwas neu zu Haskell und ich konnte keine Antworten im Internet finden Problem. Bitte helfen Sie mir :(Vielen Dank im Voraus.
(PS) Ich habe versucht mit der Weitergabe Liste der besuchten Knoten, aber es hat nicht funktioniert, weil bei Rekursion zurückkehrt, wird die Liste der besuchten Knoten auch zurückkehren, so dass es unmöglich um Daten zu verfolgen.Wenn es eine Möglichkeit gibt, 'Karte' oder 'Liste' global zu machen, ist es möglich, es auf diese Art zu implementieren. Die Antwort unten ist trotz einer Link-nur-Antwort, hat eine große Erklärung dafür, warum dies nicht sein kann (oder sollte nicht) implementiert
Danke für die Antwort, ich möchte alle Antworten als Antwort auf meine Frage wählen, aber da dies die einfachste und verallgemeinerte Antwort ist, werde ich dies als Antwort nehmen. Danke noch einmal. – MazaYong
Wow das erfordert einige ernsthafte Biegungen, um meinen Kopf herumzuwickeln. Ich verstehe immer noch nicht, wie sie den besuchten Staat kodieren, muss sich wieder dieses Papier ansehen. Nettes Beispiel und danke für die Einführung in dieses Konzept! –
@NiklasB. Das wirklich schlaue an impliziten Graphen ist, dass der besuchte Zustand gar nicht codiert werden muss. Die Funktion 'match' erzeugt (im' Just'-Fall) eine * Zerlegung * des Graphen auf 'v': Der Graph' g'' im Beispiel ist der Graph, der alle Ecken außer 'v' und alle Kanten enthält außer denen mit "v". Das liegt daran, dass der Graph im Wesentlichen eine Liste von Kontexten ist, so dass man einfach den gegebenen Kontext entfernen kann (offensichtlich ist dies mit unveränderlichen Daten auf eine effiziente Art und Weise nicht-trivial, aber dafür sind Bibliotheken :-)) – jjm