Guest User

Untitled

a guest
Jan 22nd, 2018
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.21 KB | None | 0 0
  1. (defn- pivot-partition
  2. "Partition values into (less-than, equal-to, greater-than) the pivot value"
  3. [argvals keyfn pivotval]
  4. (loop [curval (first argvals)
  5. vals (rest argvals)
  6. lt (transient (vector))
  7. p (transient (vector))
  8. gt (transient (vector))]
  9. (if (nil? curval)
  10. [(persistent! lt) (persistent! p) (persistent! gt)]
  11. (recur (first vals)
  12. (rest vals)
  13. (if (< (keyfn curval) (keyfn pivotval))
  14. (conj! lt curval)
  15. lt)
  16. (if (== (keyfn curval) (keyfn pivotval))
  17. (conj! p curval)
  18. p)
  19. (if (> (keyfn curval) (keyfn pivotval))
  20. (conj! gt curval)
  21. gt)))))
  22.  
  23. (defn- random-element
  24. "Return a random element from vector v"
  25. [v]
  26. (nth v (.nextInt rng (count v))))
  27.  
  28. (defn- randomly-pivot
  29. "Randomly select a pivot element and partition collection with respect to it"
  30. [v keyfn]
  31. (pivot-partition v keyfn (random-element v)))
  32.  
  33. (defn top-k
  34. "Use quicksort-style pivots to find top k items in expected linear time"
  35. ([v k]
  36. (top-k v identity k))
  37. ([v keyfn k]
  38. (let [[lt p gt] (randomly-pivot v keyfn)]
  39. (cond
  40. ;; Top k are entirely contained in less-than set
  41. (> (count lt) k)
  42. (top-k lt keyfn k)
  43. ;; Top k are exactly equal to less-than set (what luck!)
  44. (== (count lt) k)
  45. lt
  46. ;; Top k consist of less-than set, plus...?
  47. (< (count lt) k)
  48. (cond
  49. ;; some, but not all, of the pivot items
  50. (> (+ (count lt) (count p)) k)
  51. (concat lt (take (- k (count lt)) p))
  52. ;; exactly all of the pivot items
  53. (== (+ (count lt) (count p)) k)
  54. (concat lt p)
  55. ;; all of the pivot items, plus some of the greater-than set
  56. (< (+ (count lt) (count p)) k)
  57. (concat lt p (top-k gt keyfn (- k (+ (count lt) (count p))))))))))
  58.  
  59. ;;topk.topk> (def rvals (for [i (range 1000000)] (.nextInt rng 100000000)))
  60. ;;#'topk.topk/rvals
  61. ;;topk.topk> (time (take 10 (sort rvals)))
  62. ;;"Elapsed time: 4105.471 msecs"
  63. ;;(76 89 386 476 619 708 798 842 843 891)
  64. ;;topk.topk> (time (top-k rvals 10))
  65. ;;"Elapsed time: 288.22 msecs"
  66. ;;(619 89 386 476 76 708 798 842 843 891)
Add Comment
Please, Sign In to add comment