2012-03-21 24 views
7

Necesito hacer transformaciones a un subcampo, y podría necesitar hacer transformaciones en un subcampo del subcampo, y así sucesivamente.Modificación de matrices en Haskell y recordando índices

¿Hay formas intuitivas de hacer esto en Haskell, como definir un subcampo o algo así? Leí la sección sobre arreglos en "una introducción suave a Haskell", y no lo aborda, y me cuesta encontrar la manera de hacerlo.

Es para una implementación del algoritmo húngaro como se describe here en wikipedia.

Así que hasta ahora he hecho lo siguiente:

import Array 

step1 :: (Ord a , Num a) => Array (Int,Int) a -> Array (Int,Int) a 
step1 a  = a // [ ((i,j), f (i,j)) | (i,j) <- range (bounds a) ] where 
    f (i,j) = a!(i,j) - minRow i 
    minRow i = minimum [ a!(i,j) | j <- [1..(snd . snd . bounds) a] ] 

step2 :: (Ord a , Num a) => Array (Int,Int) a -> Array (Int,Int) a 
step2 a  = a // [ ((i,j), f (i,j)) | (i,j) <- range (bounds a) ] where 
    f (i,j) = a!(i,j) - minCol j 
    minCol j = minimum [ a!(i,j) | i <- [1..(fst . snd . bounds) a] ] 

El problema es que no sé cómo poner en práctica los pasos 3 y 4, que continúa el procedimiento en una submatriz, en caso de que una solución es no disponible.

+0

Hay algún código de muestra en Hackage que podría ayudar, consulte http://hackage.haskell.org/packages/archive/Munkres/0.1/doc/html/src/Data-Algorithm-Munkres.html#hungarianMethodInt –

+0

Hay una gran cantidad de código aquí que realmente no entiendo. Por ejemplo, ¿cómo se define el operador '@'? Se usa en aproximadamente cada segunda línea, en expresiones como 'xxs @ (x: xs)'. – Undreren

+0

El operador '@' se usa para dar un nombre a los componentes que coinciden con un patrón. Significa que 'xxs' se puede usar para referirse a la expresión que coincide con' (x: xs) ' –

Respuesta

1

Encontré una manera de evitar el problema, aunque es un poco complicado. Y solo funciona en arreglos 2D, es decir, matrices del tipo Array (Int,Int) Int. Esto es lo que hice:

import Data.Array 
import Control.Applicative 

updateSubArr :: [Int] -> [Int] -> (Array (Int,Int) Int -> Array (Int,Int) Int) 
         -> Array (Int,Int) Int -> Array (Int,Int) Int 
updateSubArr rows cols f arr = arr // (zip [(i,j) | i <- rows, j <- cols ] 
           [ fSubArr!i | i <- range $ bounds subArr ]) where 
fSubArr = f subArr 
subArr = subArray cols rows arr 

subArray rows cols arr = subArr where 
    js  = length cols 
    is  = length rows 
    subArr  = array subBounds $ zip (range subBounds) 
          [ arr!(i,j) | i <- rows, j <- cols ] 
    subRange = range subBounds 
    subBounds = ((1,1),(is,js)) 

Podría esto ser hecho para trabajar para un general Array a b?

Cuestiones relacionadas