2010-06-29 4 views
1

J'ai une structure appelée Patch qui représente un tableau 2D de données. Je souhaite construire un patch plus grand à partir d'un ensemble de patchs plus petits et de leurs positions assignées. (Les correctifs ne se chevauchent pas.) La fonction ressemble à ceci:Comment copier efficacement des tableaux bidimensionnels d'octets dans un tableau 2D plus grand?

newtype Position = (Int, Int) 

combinePatches :: [(Position, Patch)] -> Patch 
combinePatches plan = undefined 

Je vois deux sous-problèmes. D'abord, je dois définir une fonction pour traduire des copies de tableau 2D en un ensemble de copies de tableau 1D. Deuxièmement, je dois construire le dernier patch de toutes ces copies.

Notez que le patch final sera environ 4 Mo de données. C'est pourquoi je veux éviter une approche naïve.

Je suis assez confiant que je pouvais le faire horriblement inefficacement, mais je voudrais quelques conseils sur la façon de manipuler efficacement de grands tableaux 2D dans Haskell. J'ai regardé la bibliothèque "vector", mais je ne l'ai jamais utilisée auparavant.

Merci pour votre temps.

+0

Les patchs ne se chevauchent pas, mais couvrent-ils l'ensemble rectangle résultant? – yatima2975

+0

Je ne suis pas au courant d'une solution vraiment sympa pour cela dans n'importe quelle langue. Mais je ne suis pas clair sur le contexte plus large de votre cas d'utilisation. Il peut y avoir d'autres choses connues qui changent l'image. Est-ce une opération répétée, ou seulement une fois? Est-ce que vous faites des opérations intermédiaires sur des patchs composés? Ou recherchez-vous simplement une solution qui correspond, par exemple, idiomatique C? – sclv

+0

@ yatima2975: Ils ne couvrent pas tout le rectangle. @sclv: Ce n'est pas quelque chose que je fais en temps réel, mais je préférerais que cela ne prenne pas plus d'une minute. C'est le genre de chose qui serait rapide en C, sinon élégant. Je veux juste une approche raisonnablement efficace pour faire toutes ces copies. Qu'entendez-vous par "opérations intermédiaires sur des parcelles composées"? –

Répondre

2

Si la spécification est vraiment juste une création unique d'un nouveau patch d'un ensemble de précédents et de leurs positions, alors c'est un algorithme simple passe simple. Conceptuellement, j'y penserais en deux étapes - d'abord, combiner les correctifs existants dans une structure de données avec une recherche raisonnable pour n'importe quelle position donnée. Ensuite, écrivez paresseusement votre nouvelle structure en interrogeant la structure composée. Cela devrait être approximativement O (n log (m)) - n étant la taille du nouveau tableau que vous écrivez, et m étant le nombre de patches.

C'est conceptuellement beaucoup plus simple si vous utilisez la bibliothèque Vector au lieu d'un ByteString brut. Mais c'est encore plus simple si vous utilisez simplement Data.Array.Unboxed. Si vous avez besoin de tableaux pouvant interopérer avec C, utilisez plutôt Data.Array.Storable.

Si vous fossé la pureté, au moins localement, et travailler avec un tableau ST, vous devriez être en mesure de faire ce trivialement en O (n). Bien sûr, les facteurs constants seront encore pire que d'utiliser la copie rapide de blocs de mémoire à la fois, mais il n'y a aucun moyen d'empêcher ce code de paraître de bas niveau.

+0

Ou utilisez Data.Vector.Storable.Vector/MVector (et geler à partir de ST). –

+0

Droit - vous devriez pouvoir utiliser le découpage et la copie pour le retirer dans quelque chose qui semble légèrement plus propre que l'idiomatique C. Mais ma préférence, à moins que j'ai vraiment besoin de la performance supplémentaire, serait d'écrire quelque chose avec les librairies Array penser à des index pour moi, avec un certain coût constant. – sclv

Questions connexes