Advertisement
Guest User

Untitled

a guest
Nov 20th, 2017
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. Block :: {top, left, width, height}
  3.  
  4. BlockTree :: {block: Block, children: [BlockTree]}
  5.  
  6. blockTreeOfBlocks :: [Block] -> BlockTree
  7.  
  8. let size block := block.height * block.width
  9.  
  10. let within block1 block2 :=
  11.     let beginX = block2.left
  12.         beginY = block2.top
  13.         endX   = beginX + block2.width
  14.         endY   = beginY + block2.height
  15.     in block1.top > beginY && (block1.top + block1.height) < endY
  16.     && block1.left > beginX && (block1.left + block1.width) < endX
  17.  
  18. let blocksWithin blocks block := filter (\b -> b `within` block) blocks
  19.  
  20. // determina se um bloco é filho de algum irmão.
  21. // complexidade: O(n)
  22. let immediateChild child siblings :=
  23.     and (map (\sibling -> not (child `within` sibling)) siblings)
  24.  
  25. // divide uma lista de blocos em filhos diretos (aqueles que não são filhos de nenhum irmão)
  26. // e filhos indiretos (aqueles que são). Esta função espera receber os blocos ordenados por tamanho
  27. // por questão de otimização (um bloco não pode ser filho de um bloco menor do que ele)
  28. // complexidade: O(n^2). O pior caso ocorre quando todos os blocos são filhos diretos.
  29. let partitionChildren children :=
  30.     let partitionR children (immediates, nonImmediates) :=
  31.         case children of
  32.             child :: rest -> if (child `immediateChild` immediates)
  33.                              then partitionR rest (child :: immediates, nonImmediates)
  34.                              else partitionR rest (immediates, child :: nonImmediates)
  35.             []            -> (immediates, nonImmediates)
  36.     in partitionR children ([], [])
  37.  
  38.  
  39. // recebe uma lista de blocos, uma lista de filhos diretos, e uma lista de filhos indiretos e monta
  40. // uma árvore. Para cada um dos filhos diretos, são determinados quais estão ou não contidos naquele filho,
  41. // e são divididos em filhos diretos e filhos indiretos para a nova chamada recursiva.
  42.  
  43. // A princípio, isso seria uma operação de custo N * M^2 sem contar a recursão,
  44. // onde N é o número de filhos diretos
  45. // e M o de filhos indiretos, mas quando o custo da operação de partição se aproxima de M^2 não há
  46. // chamada recursiva (porque todos os filhos são diretos). Ou seja, se o número de filhos da árvore é
  47. // alto, o custo em cada nível fica baixo e vice-versa. No caso de uma árvore binária, o custo fica
  48. // N em cada nível * log N níveis, ou seja N log N, e no caso de uma árvore com apenas um nível,
  49. // o custo tende a N^2. Nos casos intermediários, o custo fica entre N log N e N^2.
  50. // Portanto, podemos concluir que a complexidade desta operação é O(N^2).
  51. let blockTreeNode parent immediateChildrenBlocks nonImmediateChildrenBlocks :=
  52.     let childrenTrees = map (\child ->
  53.             let childrenOfChild = (nonImmediateChildrenBlocks `blocksWithin` child) `sortBy` size
  54.                 (immediateChildrenOfChild, nonImmediateChildrenOfChild) = partitionChildren childrenOfChild
  55.             in blockTreeNode child immediateChildrenOfChild nonImmediateChildrenOfChild
  56.         ) immediateChildrenBlocks
  57.     in BlockTree parent childrenTrees
  58.  
  59. // A função principal só inicia a recursão adicionando uma operação em tempo constante.
  60. // Portanto, a complexidade total é O(N^2)
  61. let blockTreeOfBlocks blocks :=
  62.     let (parent :: children) = blocks `sortBy` size
  63.         (immediateChildren, nonImmediateChildren) = partitionChildren children
  64.     in blockTreeNode parent immediateChildren nonImmediateChildren
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement