Sorting Clojure中对大矢量数据进行排序的最快方法

Sorting Clojure中对大矢量数据进行排序的最快方法,sorting,clojure,Sorting,Clojure,我需要能够以这样一种方式存储来自集合的数据,即任何给定密钥集的平均值不大于特定的数字 例如,假设任何给定的3个集合的“:num”的平均值不能大于或等于10,我有以下集合: (def my-set ({:num 0} {:num 0} {:num 0} {:num 5} {:num 5} {:num 5} {:num 10} {:num 10} {:num 10} )) 在此集合中,最后3个哈希不能保持彼此相

我需要能够以这样一种方式存储来自集合的数据,即任何给定密钥集的平均值不大于特定的数字

例如,假设任何给定的3个集合的“:num”的平均值不能大于或等于10,我有以下集合:

(def my-set
    ({:num 0}
     {:num 0}
     {:num 0}
     {:num 5}
     {:num 5}
     {:num 5}
     {:num 10}
     {:num 10}
     {:num 10}
))
在此集合中,最后3个哈希不能保持彼此相邻,因为它们的平均值为10,但可以这样重新组织集合,因为任何给定3个哈希的平均值为5:

(def my-set
        ({:num 0}
         {:num 5}
         {:num 10}
         {:num 0}
         {:num 5}
         {:num 10}
         {:num 0}
         {:num 5}
         {:num 10}
    ))
我的问题是,假设这个集合比9个条目的样本大得多,可能有数百万条,而整个集合的总平均数是5条或更少,那么什么是对这些条目进行排序的最快和最有效的方法,以使任何3条(或10条或100条,或任何给定的样本大小)的平均数永远不会达到10条

以下是我的psuedocode解决方案,我觉得太慢了:

1) 按值对集合排序:number 2) 将集合除以2,然后按该索引的编号拆分 3) 以与第二个集合相反的顺序交错第一个集合

因此,第一个集合看起来像:

({:num 0} {:num 0} {:num 0} {:num 5})
和第二次收集(反向):

使用交织,生成的集合将是:

({:num 0}{:num 10}{:num 0}{:num 10}{:num 0}{:num 10}{:num 5}{:num 5}{:num 5})


一定有更好的方法做这件事。

这里有一种方法:

(def data-9
  [{:num 0}
   {:num 0}
   {:num 0}
   {:num 5}
   {:num 5}
   {:num 5}
   {:num 10}
   {:num 10}
   {:num 10}] )

(def data-11
  (into (vec data-9)
    [{:num 0}
     {:num 10}] ))

(defn interleave-by
  [data group-size]
  (let [data-num       (count data)
        part-size      (quot data-num group-size)
        leftover-num   (- data-num (* part-size group-size))
        data-sorted    (sort-by :num data)
        data-leftover  (take leftover-num data-sorted)
        data-use       (drop leftover-num data-sorted)
        data-parts     (partition-all part-size data-use)
        data-reordered (apply mapcat vector data-parts)
        data-final     (reduce into (vec data-leftover) data-reordered)
        ]
    data-final ))

(newline)
(println (interleave-by data-9 3))

data-num => 
9
part-size => 
3
leftover-num => 
0
data-sorted => 
({:num 0}
 {:num 0}
 {:num 0}
 {:num 5}
 {:num 5}
 {:num 5}
 {:num 10}
 {:num 10}
 {:num 10})
data-leftover => 
()
data-use => 
({:num 0}
 {:num 0}
 {:num 0}
 {:num 5}
 {:num 5}
 {:num 5}
 {:num 10}
 {:num 10}
 {:num 10})
data-parts => 
(({:num 0} {:num 0} {:num 0})
 ({:num 5} {:num 5} {:num 5})
 ({:num 10} {:num 10} {:num 10}))
data-reordered => 
({:num 0}
 {:num 5}
 {:num 10}
 {:num 0}
 {:num 5}
 {:num 10}
 {:num 0}
 {:num 5}
 {:num 10})
data-final => 
[[:num 0]
 [:num 5]
 [:num 10]
 [:num 0]
 [:num 5]
 [:num 10]
 [:num 0]
 [:num 5]
 [:num 10]]
(interleave-by data-9 3) => 
[[:num 0]
 [:num 5]
 [:num 10]
 [:num 0]
 [:num 5]
 [:num 10]
 [:num 0]
 [:num 5]
 [:num 10]]
如果没有组大小的整数倍,则更困难。这会导致额外的复杂性,包括
剩余数据

(newline)
(println (interleave-by data-11 3))


data-num => 
11
part-size => 
3
leftover-num => 
2
data-sorted => 
({:num 0}
 {:num 0}
 {:num 0}
 {:num 0}
 {:num 5}
 {:num 5}
 {:num 5}
 {:num 10}
 {:num 10}
 {:num 10}
 {:num 10})
data-leftover => 
({:num 0} {:num 0})
data-use => 
({:num 0}
 {:num 0}
 {:num 5}
 {:num 5}
 {:num 5}
 {:num 10}
 {:num 10}
 {:num 10}
 {:num 10})
data-parts => 
(({:num 0} {:num 0} {:num 5})
 ({:num 5} {:num 5} {:num 10})
 ({:num 10} {:num 10} {:num 10}))
data-reordered => 
({:num 0}
 {:num 5}
 {:num 10}
 {:num 0}
 {:num 5}
 {:num 10}
 {:num 5}
 {:num 10}
 {:num 10})
data-final => 
[{:num 0}
 {:num 0}
 [:num 0]
 [:num 5]
 [:num 10]
 [:num 0]
 [:num 5]
 [:num 10]
 [:num 5]
 [:num 10]
 [:num 10]]
(interleave-by data-11 3) => 
[{:num 0}
 {:num 0}
 [:num 0]
 [:num 5]
 [:num 10]
 [:num 0]
 [:num 5]
 [:num 10]
 [:num 5]
 [:num 10]
 [:num 10]]
  • 这是关于算法的,只是顺便说一下与 克罗朱尔
  • 所需要的不是这样的排序。我们正在寻找一个合适的人选 对数据进行排列,使相邻的三个(或多个)数据不存在 数字平均为5或更多。我们可以先把数字映射到 导出排列
  • 不必有任何解决办法。例如,如果任何数字大于 十五,没有一个
  • 这看起来类似于。很可能是这样 精确的解决方案是难以解决的,但贪婪的或其他的方法会解决这个问题 要实事求是

我建议你试着把这个问题放在电脑上

谢谢你!我刚刚意识到在我求解算法的逻辑中有一些主要的缺陷,但我相信这些信息在将来会派上用场。您可能的数值集是否受到已知项的限制?就像您的示例中的
{0510}
或者集合中可能有任意数字(我的意思是您是否有一些已知的约束,或者只是一些随机输入集合)?
(newline)
(println (interleave-by data-11 3))


data-num => 
11
part-size => 
3
leftover-num => 
2
data-sorted => 
({:num 0}
 {:num 0}
 {:num 0}
 {:num 0}
 {:num 5}
 {:num 5}
 {:num 5}
 {:num 10}
 {:num 10}
 {:num 10}
 {:num 10})
data-leftover => 
({:num 0} {:num 0})
data-use => 
({:num 0}
 {:num 0}
 {:num 5}
 {:num 5}
 {:num 5}
 {:num 10}
 {:num 10}
 {:num 10}
 {:num 10})
data-parts => 
(({:num 0} {:num 0} {:num 5})
 ({:num 5} {:num 5} {:num 10})
 ({:num 10} {:num 10} {:num 10}))
data-reordered => 
({:num 0}
 {:num 5}
 {:num 10}
 {:num 0}
 {:num 5}
 {:num 10}
 {:num 5}
 {:num 10}
 {:num 10})
data-final => 
[{:num 0}
 {:num 0}
 [:num 0]
 [:num 5]
 [:num 10]
 [:num 0]
 [:num 5]
 [:num 10]
 [:num 5]
 [:num 10]
 [:num 10]]
(interleave-by data-11 3) => 
[{:num 0}
 {:num 0}
 [:num 0]
 [:num 5]
 [:num 10]
 [:num 0]
 [:num 5]
 [:num 10]
 [:num 5]
 [:num 10]
 [:num 10]]