[英]Sampling with no replacement in Java from an ArrayList
我有一個包含 30 個元素的數組列表。 我想從此列表中創建許多包含 15 個元素的子列表。 這樣做的有效方法是什么?
現在我克隆 ArrayList 並使用 remove(random) 來完成它,但我確信這太笨拙了。 我應該怎么做? Java 是否有像 R 中的“樣本”函數?
澄清:通過無替換抽樣,我的意思是從原始列表中的 30 個可用元素中隨機抽取15 個獨特元素。 此外,我希望能夠反復這樣做。
使用Collections#shuffle
方法來打亂你的原始列表,並返回一個包含前 15 個元素的列表。
考慮創建新列表並從當前列表中添加隨機元素,而不是復制所有元素並刪除它們。
另一種方法是在當前列表的頂部創建某種View
。
實現一個Iterator
接口,該接口next
操作期間隨機生成元素索引,並從當前列表中按索引檢索元素。
不,Java 沒有像 R 中那樣的示例函數。但是,可以編寫這樣的函數:
// Samples n elements from original, and returns that list
public <T> static List<T> sample(List<T> original, int n) {
List<T> result = new ArrayList<T>(n);
for (int i = 0; i < original.size(); i++) {
if (result.size() == n)
return result;
if ((n - result.size()) >= (original.size() - i)) {
result.add(original.get(i));
} else if (Math.random() < ((double)n / original.size())) {
result.add(original.get(i));
}
}
return result;
}
此函數遍歷original
,並根據隨機數將當前元素復制到result
,除非我們離original
的末尾足夠近而需要復制所有剩余元素(循環中的第二個 if 語句)。
這是一個基本的組合問題。 您的列表中有 30 個元素,並且您想選擇 15 個。如果順序很重要,則需要排列,如果不重要,則需要組合。
網絡上有各種 Java 組合學示例,它們通常使用combinadics 。 我不知道任何現成的 Java 庫,但Apache Math Commons支持二項式系數,如果你走這條路,可以幫助你實現組合。 一旦你有一個從 0 到 29 的 15 個索引序列,我建議創建一個只讀迭代器,你可以從中讀取元素。 這樣您就不必創建任何新列表或復制任何參考。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.