Estoy escribiendo un algoritmo para encontrar caminos largos en varios puntos de giro dada una lista de coordenadas (que describen una ruta). El algoritmo de programación dinámica funciona bien en O (kn^2), donde k es el número de puntos de giro yn número de puntos. Para abreviar la historia: la parte más lenta es el cálculo de distancia entre 2 coordenadas; el algoritmo requiere que esto sea 'k' multiplicado por el mismo par de puntos. La memorización no es una opción (demasiados puntos). Es posible 'invertir' el algoritmo, pero de alguna manera el algoritmo invertido es muy lento en haskell y come demasiada memoria.Encontrar de manera eficiente múltiples máximos en la lista de listas en Haskell
Me parece que el problema sigue; se le da una matriz de matrices de tamaño fijo (más algo de valor de forma dinámica computarizada - por ejemplo, este sería el resultado de comprimir el valor de la lista:
arr = [ (2, [10,5,12]), (1, [2,8, 20]), (4, [3, 2, 10]) ]
Estoy tratando de encontrar un máximo sobre los elementos de la lista más el valor fijo:
[12, 9, 21]
lo que estoy haciendo - algo así como:
foldl' getbest (replicate 3 0) arr
getbest acc (fixval, item) = map comparator $ zip acc item
comparator orig new
| new + fixval > orig = new + fixval
| otherwise = orig
el problema es que un nuevo 'ACC' se construye con cada llamada a 'getbest' - el cual es n^2, que es mucho. La asignación es costosa y este es probablemente el problema. ¿Tienes alguna idea de cómo hacer tal cosa de manera eficiente?
Para que quede claro: este es el código real de la función:
dynamic2FreeFlight :: Int -> [ Coord ] -> [ Coord ]
dynamic2FreeFlight numpoints points = reverse $ (dsCoord bestPoint) : (snd $ (dsScore bestPoint) !! (numpoints - 2))
where
bestPoint :: DSPoint
bestPoint = maximumBy (\x y -> (getFinalPointScore x) `compare` (getFinalPointScore y)) compresult
getFinalPointScore :: DSPoint -> Double
getFinalPointScore sc = fst $ (dsScore sc) !! (numpoints - 2)
compresult :: [ DSPoint ]
compresult = foldl' onestep [] points
onestep :: [ DSPoint ] -> Coord -> [ DSPoint ]
onestep lst point = (DSPoint point (genmax lst)) : lst
where
genmax :: [ DSPoint ] -> [ (Double, [ Coord ]) ]
genmax lst = map (maximumBy comparator) $ transpose prepared
comparator a b = (fst a) `compare` (fst b)
distances :: [ Double ]
distances = map (distance point . dsCoord) lst
prepared :: [ [ (Double, [ Coord ]) ] ]
prepared
| length lst == 0 = [ replicate (numpoints - 1) (0, []) ]
| otherwise = map prepare $ zip distances lst
prepare :: (Double, DSPoint) -> [ (Double, [ Coord ]) ]
prepare (dist, item) = (dist, [dsCoord item]) : map addme (take (numpoints - 2) (dsScore item))
where
addme (score, coords) = (score + dist, dsCoord item : coords)
'[a, b, c]' IS * no * una matriz, es una lista (individualmente unida). – sepp2k
¿De dónde viene '[12, 9, 21]'? – Gabe
12 es el máximo del 'primer artículo + número fijo' (es decir, 10 + 2), 9 es el 'segundo artículo + número fijo (8 + 1)' etc. – ondra