Declaratieve Talen/Oplossing Graaf-isomorfie: verschil tussen versies
Naar navigatie springen
Naar zoeken springen
juiste oef |
alternatieve oplossing |
||
Regel 30: | Regel 30: | ||
then False | then False | ||
else vergelijk2 bogen1 bogen2 (combs knopen1 knopen2) | else vergelijk2 bogen1 bogen2 (combs knopen1 knopen2) | ||
vergelijk::(Eq t,Eq u)=>[(t,t)]->[(u,u)]->[ [(t,u)] ]->[(t,u)] | vergelijk::(Eq t,Eq u)=>[(t,t)]->[(u,u)]->[ [(t,u)] ]->[(t,u)] | ||
-------------------------------------------------------------- | -------------------------------------------------------------- | ||
Regel 37: | Regel 37: | ||
vergelijk _ _ [[]] = error "Geen gelijkenis gevonden" | vergelijk _ _ [[]] = error "Geen gelijkenis gevonden" | ||
vergelijk b1 b2 (comb:rest) | controleer b1 b2 comb = comb | vergelijk b1 b2 (comb:rest) | controleer b1 b2 comb = comb | ||
| otherwise = vergelijk b1 b2 rest | |||
vergelijk2::(Eq t,Eq u)=>[(t,t)]->[(u,u)]->[ [(t,u)] ]->Bool | vergelijk2::(Eq t,Eq u)=>[(t,t)]->[(u,u)]->[ [(t,u)] ]->Bool | ||
------------------------------------------------------------ | ------------------------------------------------------------ | ||
Regel 45: | Regel 45: | ||
vergelijk2 b1 b2 (comb:rest) | controleer b1 b2 comb = True | vergelijk2 b1 b2 (comb:rest) | controleer b1 b2 comb = True | ||
| otherwise = vergelijk2 b1 b2 rest | | otherwise = vergelijk2 b1 b2 rest | ||
controleer::(Eq t,Eq u)=>[(t,t)]->[(u,u)]->[(t,u)]->Bool | controleer::(Eq t,Eq u)=>[(t,t)]->[(u,u)]->[(t,u)]->Bool | ||
-------------------------------------------------------- | -------------------------------------------------------- | ||
Regel 85: | Regel 85: | ||
check g1 (sub:rest) | iso2 g1 sub = True | check g1 (sub:rest) | iso2 g1 sub = True | ||
| otherwise = check g1 rest | | otherwise = check g1 rest | ||
maakDeelGraaf::(Ord u)=>([u],[(u,u)])->[([u],[(u,u)])] | maakDeelGraaf::(Ord u)=>([u],[(u,u)])->[([u],[(u,u)])] | ||
----------------------------------------------------- | ----------------------------------------------------- | ||
Regel 94: | Regel 94: | ||
in | in | ||
combineerMetBogen deelKnopen bogen | combineerMetBogen deelKnopen bogen | ||
combineerMetBogen::(Eq u)=>[ [u] ]->[(u,u)]->[([u],[(u,u)])] | combineerMetBogen::(Eq u)=>[ [u] ]->[(u,u)]->[([u],[(u,u)])] | ||
---------------------------------------------------------- | ---------------------------------------------------------- | ||
Regel 110: | Regel 110: | ||
then boog:(bogen2 knopen rest) | then boog:(bogen2 knopen rest) | ||
else bogen2 knopen rest | else bogen2 knopen rest | ||
maakDeelKnopen::(Ord u)=>[u]->[ [u] ] | maakDeelKnopen::(Ord u)=>[u]->[ [u] ] | ||
------------------------------------- | ------------------------------------- | ||
maakDeelKnopen knopen = nub [sort y|x<-(perms knopen),y<-inits x] | maakDeelKnopen knopen = nub [sort y|x<-(perms knopen),y<-inits x] | ||
combs::[t]->[u]->[ [(t,u)] ] | combs::[t]->[u]->[ [(t,u)] ] | ||
---------------------------- | ---------------------------- | ||
Regel 123: | Regel 123: | ||
combineer _ [[]] = [[]] | combineer _ [[]] = [[]] | ||
combineer lijst (x:xs) = (zip lijst x):(combineer lijst xs) | combineer lijst (x:xs) = (zip lijst x):(combineer lijst xs) | ||
perms::[u]->[ [u] ] | perms::[u]->[ [u] ] | ||
------------------- | ------------------- | ||
perms [] = [[]] | perms [] = [[]] | ||
perms (x:xs) = concatMap (interleave x) (perms xs) | perms (x:xs) = concatMap (interleave x) (perms xs) | ||
interleave::u->[u]->[ [u] ] | interleave::u->[u]->[ [u] ] | ||
--------------------------- | --------------------------- | ||
interleave x [] = [ [x] ] | interleave x [] = [ [x] ] | ||
interleave x (y:ys) = [x:y:ys]++map (y:) (interleave x ys) | interleave x (y:ys) = [x:y:ys]++map (y:) (interleave x ys) | ||
=== alternatief voor het eerste deel === | |||
iso_f::(Eq t,Eq u)=>([t],[(t,t)])->([u],[(u,u)])->[(t,u)]--iso_f geeft de bijectie f, iso gewoon een bool | |||
---------------------------------------------------- | |||
iso_f ((v1:[]),e1) ((v2:[]),e2) = [(v1,v2)] | |||
iso_f ((v1:v1s),e1) (v2,e2) = | |||
let graad_v1 = length [(a,b) | (a,b) <- e1, (a==v1 ||b==v1)] | |||
candidates = knopen_met_graad graad_v1 v2 e2 | |||
subgraaf = graaf_zonder v1 ((v1:v1s),e1) | |||
in iso_f2 v1 subgraaf (v2,e2) candidates | |||
iso_f2::(Eq t,Eq u)=>t ->([t],[(t,t)])->([u],[(u,u)])-> [u]->[(t,u)] | |||
----------------------------------------------------------- | |||
iso_f2 v1 subgraaf graaf [] = [] | |||
iso_f2 v1 subgraaf graaf (c1:candidates) = | |||
let iso_graaf = graaf_zonder c1 graaf | |||
in | |||
if not $ null (iso_f subgraaf iso_graaf) | |||
then (v1,c1):(iso_f subgraaf iso_graaf) | |||
else (iso_f2 v1 subgraaf graaf candidates) | |||
graaf_zonder:: (Eq t) => t -> ([t],[(t,t)]) -> ([t],[(t,t)]) --wist t uit de lijst van knopen en alle bogen naar/van t | |||
-------------------------------------------------- | |||
graaf_zonder knoop (knopen, bogen)= | |||
let nieuwe_knopen = [y |y <- knopen, y /= knoop] | |||
nieuwe_bogen = [(begin, eind) | (begin, eind) <-bogen, begin /= knoop, eind /= knoop] | |||
in (nieuwe_knopen, nieuwe_bogen) | |||
knopen_met_graad::(Eq t) => Int -> [t] ->[(t,t)] -> [t]--lijst met knopen van graad 'Int' | |||
------------------------------------------ | |||
knopen_met_graad x [] bogen = [] | |||
knopen_met_graad x (k:ks) bogen = | |||
let graadk = length [(a,b) | (a,b) <- bogen, (a==k ||b==k)] | |||
in | |||
if graadk == x | |||
then k:knopen_met_graad x ks bogen | |||
else knopen_met_graad x ks bogen | |||
voor de duidelijkheid iso die gewoon een bool geeft, iso_f is hier een uitbreiding op: | |||
iso::(Eq t,Eq u)=>([t],[(t,t)])->([u],[(u,u)])->Bool | |||
---------------------------------------------------- | |||
iso ((v1:[]),e1) ((v2:[]),e2) = True | |||
iso ((v1:v1s),e1) (v2,e2) = | |||
let graad_v1 = length [(a,b) | (a,b) <- e1, (a==v1 ||b==v1)] | |||
candidates = knopen_met_graad graad_v1 v2 e2 | |||
subgraaf = graaf_zonder v1 ((v1:v1s),e1) | |||
in iso2 subgraaf (v2,e2) candidates | |||
iso2::(Eq t,Eq u)=>([t],[(t,t)])->([u],[(u,u)])-> [u]->Bool --iso met een van de grafen na verwijderen van een candidate? | |||
----------------------------------------------------------- | |||
iso2 subgraaf graaf [] = False | |||
iso2 subgraaf graaf (c1:candidates) = | |||
let iso_graaf = graaf_zonder c1 graaf | |||
in (iso subgraaf iso_graaf) || (iso2 subgraaf graaf candidates) | |||
--[[Gebruiker:Beau|Beau]] 17 jun 2006 15:48 (CEST) |
Huidige versie van 17 jun 2006 13:48
Een oplossing:
import List iso::(Eq t,Eq u)=>([t],[(t,t)])->([u],[(u,u)])->[(t,u)] ------------------------------------------------------- iso graaf1 graaf2 = let (knopen1,bogen1) = graaf1 (knopen2,bogen2) = graaf2 cond1 = length knopen1 /= length knopen2 cond2 = length bogen1 /= length bogen2 in if cond1 then error "Knooplijsten zijn van verschillende lengte!!!" else if cond2 then error "Booglijsten zijn van verschillende lengte!!!" else vergelijk bogen1 bogen2 (combs knopen1 knopen2) iso2::(Eq t,Eq u)=>([t],[(t,t)])->([u],[(u,u)])->Bool ----------------------------------------------------- iso2 graaf1 graaf2 = let (knopen1,bogen1) = graaf1 (knopen2,bogen2) = graaf2 cond1 = length knopen1 /= length knopen2 cond2 = length bogen1 /= length bogen2 in if cond1 || cond2 then False else vergelijk2 bogen1 bogen2 (combs knopen1 knopen2) vergelijk::(Eq t,Eq u)=>[(t,t)]->[(u,u)]->[ [(t,u)] ]->[(t,u)] -------------------------------------------------------------- vergelijk _ _ [] = error "Geen gelijkenis gevonden" vergelijk _ _ [[]] = error "Geen gelijkenis gevonden" vergelijk b1 b2 (comb:rest) | controleer b1 b2 comb = comb | otherwise = vergelijk b1 b2 rest vergelijk2::(Eq t,Eq u)=>[(t,t)]->[(u,u)]->[ [(t,u)] ]->Bool ------------------------------------------------------------ vergelijk2 _ _ [] = False vergelijk2 _ _ [[]] = False vergelijk2 b1 b2 (comb:rest) | controleer b1 b2 comb = True | otherwise = vergelijk2 b1 b2 rest controleer::(Eq t,Eq u)=>[(t,t)]->[(u,u)]->[(t,u)]->Bool -------------------------------------------------------- controleer [] [] _ = True controleer (x:xs) lijst koppels = let (tvan,tnaar) = x uvan = head [b|(a,b)<-koppels,a==tvan] unaar = head [b|(a,b)<-koppels,a==tnaar] in if (zitInLijst (uvan,unaar) lijst) then controleer xs (verwijderUitLijst (uvan,unaar) lijst) koppels else False where zitInLijst::(Eq u)=>(u,u)->[(u,u)]->Bool ---------------------------------------- zitInLijst _ [] = False zitInLijst (u,v) ((x,y):rest) | (u==x) && (v==y) = True | otherwise = zitInLijst (u,v) rest verwijderUitLijst::(Eq u)=>(u,u)->[(u,u)]->[(u,u)] -------------------------------------------------- verwijderUitLijst _ [] = [] verwijderUitLijst (u,v) ((x,y):rest) | (u==x) && (v==y) = rest | otherwise = (x,y):(verwijderUitLijst (u,v) rest) subiso::(Ord t,Ord u)=>([t],[(t,t)])->([u],[(u,u)])->Bool ------------------------------------------------------- subiso graaf1 graaf2 = let (knopen1,bogen1) = graaf1 (knopen2,bogen2) = graaf2 in check graaf1 (maakDeelGraaf graaf2) where check::(Ord u,Ord t)=>([t],[(t,t)])->[([u],[(u,u)])]->Bool ---------------------------------------------------------- check _ [] = False check g1 (sub:rest) | iso2 g1 sub = True | otherwise = check g1 rest maakDeelGraaf::(Ord u)=>([u],[(u,u)])->[([u],[(u,u)])] ----------------------------------------------------- maakDeelGraaf graaf = let (knopen,bogen) = graaf deelKnopen = maakDeelKnopen knopen in combineerMetBogen deelKnopen bogen combineerMetBogen::(Eq u)=>[ [u] ]->[(u,u)]->[([u],[(u,u)])] ---------------------------------------------------------- combineerMetBogen [] _ = [] combineerMetBogen (el:rest) bogen = (el,(bogen2 el bogen)):(combineerMetBogen rest bogen) where bogen2::(Eq u)=>[u]->[(u,u)]->[(u,u)] ------------------------------------- bogen2 _ [] = [] bogen2 knopen (boog:rest) = let (van,naar) = boog in if ((van `elem` knopen) && (naar `elem` knopen)) then boog:(bogen2 knopen rest) else bogen2 knopen rest maakDeelKnopen::(Ord u)=>[u]->[ [u] ] ------------------------------------- maakDeelKnopen knopen = nub [sort y|x<-(perms knopen),y<-inits x] combs::[t]->[u]->[ [(t,u)] ] ---------------------------- combs g1 g2 = combineer g1 (perms g2) where combineer::[t]->[ [u] ]->[ [(t,u)] ] ------------------------------------ combineer _ [[]] = [[]] combineer lijst (x:xs) = (zip lijst x):(combineer lijst xs) perms::[u]->[ [u] ] ------------------- perms [] = [[]] perms (x:xs) = concatMap (interleave x) (perms xs) interleave::u->[u]->[ [u] ] --------------------------- interleave x [] = [ [x] ] interleave x (y:ys) = [x:y:ys]++map (y:) (interleave x ys)
alternatief voor het eerste deel
iso_f::(Eq t,Eq u)=>([t],[(t,t)])->([u],[(u,u)])->[(t,u)]--iso_f geeft de bijectie f, iso gewoon een bool ---------------------------------------------------- iso_f ((v1:[]),e1) ((v2:[]),e2) = [(v1,v2)] iso_f ((v1:v1s),e1) (v2,e2) = let graad_v1 = length [(a,b) | (a,b) <- e1, (a==v1 ||b==v1)] candidates = knopen_met_graad graad_v1 v2 e2 subgraaf = graaf_zonder v1 ((v1:v1s),e1) in iso_f2 v1 subgraaf (v2,e2) candidates iso_f2::(Eq t,Eq u)=>t ->([t],[(t,t)])->([u],[(u,u)])-> [u]->[(t,u)] ----------------------------------------------------------- iso_f2 v1 subgraaf graaf [] = [] iso_f2 v1 subgraaf graaf (c1:candidates) = let iso_graaf = graaf_zonder c1 graaf in if not $ null (iso_f subgraaf iso_graaf) then (v1,c1):(iso_f subgraaf iso_graaf) else (iso_f2 v1 subgraaf graaf candidates) graaf_zonder:: (Eq t) => t -> ([t],[(t,t)]) -> ([t],[(t,t)]) --wist t uit de lijst van knopen en alle bogen naar/van t -------------------------------------------------- graaf_zonder knoop (knopen, bogen)= let nieuwe_knopen = [y |y <- knopen, y /= knoop] nieuwe_bogen = [(begin, eind) | (begin, eind) <-bogen, begin /= knoop, eind /= knoop] in (nieuwe_knopen, nieuwe_bogen) knopen_met_graad::(Eq t) => Int -> [t] ->[(t,t)] -> [t]--lijst met knopen van graad 'Int' ------------------------------------------ knopen_met_graad x [] bogen = [] knopen_met_graad x (k:ks) bogen = let graadk = length [(a,b) | (a,b) <- bogen, (a==k ||b==k)] in if graadk == x then k:knopen_met_graad x ks bogen else knopen_met_graad x ks bogen
voor de duidelijkheid iso die gewoon een bool geeft, iso_f is hier een uitbreiding op:
iso::(Eq t,Eq u)=>([t],[(t,t)])->([u],[(u,u)])->Bool ---------------------------------------------------- iso ((v1:[]),e1) ((v2:[]),e2) = True iso ((v1:v1s),e1) (v2,e2) = let graad_v1 = length [(a,b) | (a,b) <- e1, (a==v1 ||b==v1)] candidates = knopen_met_graad graad_v1 v2 e2 subgraaf = graaf_zonder v1 ((v1:v1s),e1) in iso2 subgraaf (v2,e2) candidates iso2::(Eq t,Eq u)=>([t],[(t,t)])->([u],[(u,u)])-> [u]->Bool --iso met een van de grafen na verwijderen van een candidate? ----------------------------------------------------------- iso2 subgraaf graaf [] = False iso2 subgraaf graaf (c1:candidates) = let iso_graaf = graaf_zonder c1 graaf in (iso subgraaf iso_graaf) || (iso2 subgraaf graaf candidates)
--Beau 17 jun 2006 15:48 (CEST)