Representación matricial de relaciones binarias
Dada una relación r
sobre un conjunto de números enteros, la matriz asociada a r
es una matriz booleana p
(cuyos elementos son True
o False
), tal que p(i,j) = True
si y sólo si i
está relacionado con j
mediante la relación r
.
Las relaciones binarias homogéneas y las matrices booleanas se pueden representar por
1 2 |
type Relacion = ([Int],[(Int,Int)]) type Matriz = Array (Int,Int) Bool |
Definir la función
1 |
matrizRB:: Relacion -> Matriz |
tal que (matrizRB r)
es la matriz booleana asociada a r
. Por ejemplo,
1 2 3 4 5 6 7 8 9 10 |
λ> matrizRB ([1..3],[(1,1), (1,3), (3,1), (3,3)]) array ((1,1),(3,3)) [((1,1),True) ,((1,2),False),((1,3),True), ((2,1),False),((2,2),False),((2,3),False), ((3,1),True) ,((3,2),False),((3,3),True)] λ> matrizRB ([1..3],[(1,3), (3,1)]) array ((1,1),(3,3)) [((1,1),False),((1,2),False),((1,3),True), ((2,1),False),((2,2),False),((2,3),False), ((3,1),True) ,((3,2),False),((3,3),False)] λ> let n = 10^4 in matrizRB3 ([1..n],[(1,n),(n,1)]) ! (n,n) False |
Soluciones
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
import Data.Array (Array, accumArray, array, listArray) import Test.QuickCheck (Arbitrary, Gen, arbitrary, sublistOf, suchThat, quickCheck) type Relacion = ([Int],[(Int,Int)]) type Matriz = Array (Int,Int) Bool -- 1ª solución -- =========== matrizRB1 :: Relacion -> Matriz matrizRB1 r = array ((1,1),(n,n)) [((a,b), (a,b) `elem` grafo r) | a <- [1..n], b <- [1..n]] where n = maximum (universo r) universo (us,_) = us grafo (_,ps) = ps -- 2ª solución -- =========== matrizRB2 :: Relacion -> Matriz matrizRB2 r = listArray ((1,1),(n,n)) [(a,b) `elem` snd r | a <- [1..n], b <- [1..n]] where n = maximum (fst r) -- 3ª solución -- =========== matrizRB3 :: Relacion -> Matriz matrizRB3 r = accumArray (||) False ((1,1),(n,n)) (zip (snd r) (repeat True)) where n = maximum (fst r) -- Comprobación de equivalencia -- ============================ -- Tipo de relaciones binarias newtype RB = RB Relacion deriving Show -- relacionArbitraria genera una relación arbitraria. Por ejemplo, -- λ> generate relacionArbitraria -- RB ([1,2,3,4,5],[(1,4),(1,5),(2,3),(2,4),(4,2),(4,3),(4,4),(5,1),(5,2),(5,3),(5,4)]) relacionArbitraria :: Gen RB relacionArbitraria = do n <- arbitrary `suchThat` (> 1) xs <- sublistOf [(x,y) | x <- [1..n], y <- [1..n]] return (RB ([1..n], xs)) -- RB es una subclase de Arbitrary instance Arbitrary RB where arbitrary = relacionArbitraria -- La propiedad es prop_matrizRB :: RB -> Bool prop_matrizRB (RB r) = all (== matrizRB1 r) [matrizRB2 r, matrizRB3 r] -- La comprobación es -- λ> quickCheck prop_matrixzB -- +++ OK, passed 100 tests. -- Comparación de eficiencia -- ========================= -- La comparación es -- λ> let n = 2000 in matrizRB1 ([1..n],[(1,n),(n,1)]) ! (n,n) -- False -- (2.02 secs, 1,505,248,912 bytes) -- λ> let n = 2000 in matrizRB2 ([1..n],[(1,n),(n,1)]) ! (n,n) -- False -- (1.92 secs, 833,232,360 bytes) -- λ> let n = 2000 in matrizRB3 ([1..n],[(1,n),(n,1)]) ! (n,n) -- False -- (0.05 secs, 32,848,696 bytes) |
El código se encuentra en GitHub.