Declaratieve Talen/Oplossing Graaf-isomorfie: verschil tussen versies

Uit Wina Examenwiki
Naar navigatie springen Naar zoeken springen
Beau (overleg | bijdragen)
juiste oef
Beau (overleg | bijdragen)
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
      | 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)