Für Bildungszwecke habe ich vor kurzem allgemeine Algorithmen in Haskell implementiert. Zur Zeit stecke ich auf Breathth-First Search fest. Dies ist meine Implementierung mit Knoten als nur ganze Zahlen der Einfachheit halber dargestellt wird:Vermeiden von Duplikaten in der Breitensuche
import qualified Data.Map as M
import qualified Data.List as L
type Node = Int
type Graph = M.Map Node [Node]
-- Returns list of nodes adjacent to n in graph g
adjacent :: Node -> Graph -> [Node]
adjacent n g = M.findWithDefault [] n g
-- Returns graph g with all instances of n removed
rip :: Node -> Graph -> Graph
rip n g = M.delete n (M.map (L.delete n) g)
bfs :: Node -> Graph -> [Node]
bfs n g = [n] ++ _bfs [n] g
_bfs :: [Node] -> Graph -> [Node]
_bfs (n:ns) g =
if not (M.null g) then
let layer = adjacent n g in
layer ++ _bfs (ns ++ layer) (rip n g)
else n:ns
_bfs [] g = []
(Es gibt auch andere Funktionen für die grafische Darstellung tatsächlich konstruieren, aber ich ließ sie der Kürze halber out)
Das Ergebnis des Aufrufs bfs
wäre ein richtiger Breiten ersten Durchlauf des Graphen, wenn nicht für die Tatsache, dass einige Diagramme produzieren Duplikate, wie diese:
(das Ergebnis von bfs 1 g
für g
= Dieser Graph ist [1,2,3,4,4,5,6,7,7,7]
)
Meine aktuelle Lösung kocht in _bfs
-L.nub $ layer ++ _bfs (ns ++ layer) (rip n g)
die entsprechende Zeile an veränderte nach unten, aber das scheint unglaublich hackish, und ich bin nicht sicher, ob es eine richtige Breite beginn produzieren werde Durchquerung. Abgesehen davon, n:ns
für Duplikate vor dem Einfügen ständig zu überprüfen (was schrecklich ineffizient klingt), habe ich keine anderen Ideen.
Wie kann ich _bfs
(oder mehr) umschreiben, so dass es per Definition keine Duplikate erzeugt?
Monaden sind immer noch ziemlich jenseits von mir. Egal, danke für deine Antwort, ich werde es irgendwann akzeptieren, wenn ein einfacherer nicht mitkommt. –
@MoreAxes: Ich habe eine Implementierung ohne Monaden hinzugefügt, ich hoffe, es ist zugänglicher. –
Es ist, danke. Weißt du, wo ich eine Ressource über Monaden finden könnte, die sie gut erklärt? Weder die Dokumentation noch das Wiki scheinen hier hilfreich zu sein. Ist es eines dieser Dinge, die nur "klicken", wenn Sie lange genug über sie nachgedacht haben? –