match
ist in der Graph typeclass definiert, daher hängt die Implementierung dieser Funktion vom Datentyp ab, der die typeclass implementiert.
Das Paket wird mit zwei Implementierungen geliefert: one using Patricia trees, one using regular trees. Sie können die Quelle für sich selbst anzeigen.
Zum Beispiel kann die Umsetzung Patricia-Baum:
import Data.Graph.Inductive.Graph
import Data.IntMap (IntMap)
import qualified Data.IntMap as IM
import Data.List
import Data.Maybe
import Control.Arrow(second)
newtype Gr a b = Gr (GraphRep a b)
type GraphRep a b = IntMap (Context' a b)
type Context' a b = (IntMap [b], a, IntMap [b])
type UGr = Gr()()
instance Graph Gr where
-- ...
match = matchGr
-- ...
matchGr :: Node -> Gr a b -> Decomp Gr a b
matchGr node (Gr g)
= case IM.lookup node g of
Nothing
-> (Nothing, Gr g)
Just (p, label, s)
-> let !g1 = IM.delete node g
!p' = IM.delete node p
!s' = IM.delete node s
!g2 = clearPred g1 node (IM.keys s')
!g3 = clearSucc g2 node (IM.keys p')
in
(Just (toAdj p', node, label, toAdj s), Gr g3)
lookup
and delete
on IntMaps have O(min(n,W)) runtime, die auf einer gegebenen Maschine mit einem Satz ganzzahlige Breite effektiv konstant ist (W
).
dass So bleibt nur clearPred
, clearSucc
und toAdj
:
clearSucc :: GraphRep a b -> Node -> [Node] -> GraphRep a b
clearSucc g _ [] = g
clearSucc g v (p:rest) = clearSucc g' v rest
where
g' = IM.adjust f p g
f (ps, l, ss) = (ps, l, IM.delete v ss)
clearPred :: GraphRep a b -> Node -> [Node] -> GraphRep a b
clearPred g _ [] = g
clearPred g v (s:rest) = clearPred g' v rest
where
g' = IM.adjust f s g
f (ps, l, ss) = (IM.delete v ps, l, ss)
adjust
ist auch O(min(n,W))
, so brauchen wir nicht darüber Sorgen zu machen. Sowohl clearSucc
als auch clearPred
rekursiv durch jedes Element in der Adjazenzliste, so dass O (Grad) kombiniert ist.
toAdj :: IntMap [b] -> Adj b
toAdj = concatMap expand . IM.toList
where
expand (n,ls) = map (flip (,) n) ls
toAdj
erstellt eine neue Kantenliste, die O (max (| V |, | E |)), aber diese träge aufgebaut ist, so brauchen wir nicht zu kümmern, wenn es verwendet wird.
Ein Überblick auf sehr hohem Niveau - die meisten Arbeiten in der 'match'-Funktion für die gebräuchlichste Graphimplementierung verwenden die 'Lookup'-Funktion des' IntMap'-Moduls. Dies ist "O (min (n, W))", wobei "n" die Anzahl der Elemente in der Abbildung ist und "W" die Größe in Bits eines int (normalerweise entweder 32 oder 64) ist. Also ist das Nachschlagen in n linear, bis zu einem Maximum von n = 32 oder n = 64, danach ist es konstant - insbesondere ist es asymptotisch O (1). –