簡體   English   中英

從 ArrayList 在 Java 中進行無替換的采樣

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM