Mínimo producto escalar
El producto escalar de los vectores [a1,a2,...,an] y [b1,b2,..., bn] es
a1·b1 + a2·b2 + ··· + an·bn.
Definir la función
menorProductoEscalar :: (Ord a, Num a) => [a] -> [a] -> a
tal que (menorProductoEscalar xs ys) es el mínimo de los productos escalares de las permutaciones de xs y de las permutaciones de ys. Por ejemplo,
menorProductoEscalar [3,2,5] [1,4,6] == 29 menorProductoEscalar [3,2,5] [1,4,-6] == -19 menorProductoEscalar [0..9] [0..9] == 120 menorProductoEscalar [0..99] [0..99] == 161700 menorProductoEscalar [0..999] [0..999] == 166167000 menorProductoEscalar3 [0..9999] [0..9999] == 166616670000 menorProductoEscalar3 [0..99999] [0..99999] == 166661666700000 menorProductoEscalar3 [0..999999] [0..999999] == 166666166667000000
Soluciones
import Data.List (sort, permutations) import Test.QuickCheck -- 1ª solución menorProductoEscalar :: (Ord a, Num a) => [a] -> [a] -> a menorProductoEscalar xs ys = minimum [sum (zipWith (*) pxs pys) | pxs <- permutations xs, pys <- permutations ys] -- 2ª solución menorProductoEscalar2 :: (Ord a, Num a) => [a] -> [a] -> a menorProductoEscalar2 xs ys = minimum [sum (zipWith (*) pxs ys) | pxs <- permutations xs] -- 3ª solución menorProductoEscalar3 :: (Ord a, Num a) => [a] -> [a] -> a menorProductoEscalar3 xs ys = sum (zipWith (*) (sort xs) (reverse (sort ys))) -- Equivalencia -- ============ -- La propiedad es prop_menorProductoEscalar :: [Integer] -> [Integer] -> Bool prop_menorProductoEscalar xs ys = menorProductoEscalar3 xs' ys' == menorProductoEscalar xs' ys' && menorProductoEscalar3 xs' ys' == menorProductoEscalar2 xs' ys' where n = min (length xs) (length ys) xs' = take n xs ys' = take n ys -- La comprobación es -- λ> quickCheckWith (stdArgs {maxSize=7}) prop_menorProductoEscalar -- +++ OK, passed 100 tests. -- Comparación de eficiencia -- ========================= -- La comparación es -- λ> menorProductoEscalar1 [0..5] [0..5] -- 20 -- (3.24 secs, 977385528 bytes) -- λ> menorProductoEscalar2 [0..5] [0..5] -- 20 -- (0.01 secs, 4185776 bytes) -- -- λ> menorProductoEscalar2 [0..9] [0..9] -- 120 -- (23.86 secs, 9342872784 bytes) -- λ> menorProductoEscalar3 [0..9] [0..9] -- 120 -- (0.01 secs, 2580824 bytes) -- -- λ> menorProductoEscalar3 [0..10^6] [0..10^6] -- 166666666666500000 -- (2.46 secs, 473,338,912 bytes)