Выборка без замены в Java из ArrayList - PullRequest
3 голосов
/ 23 января 2012

У меня есть arrayList с 30 элементами.Я хотел бы создать много подсписков из 15 элементов из этого списка.Какой эффективный способ сделать это?

Сейчас я клонирую ArrayList и использую для этого команду remove (random), но я уверен, что это слишком неуклюже.Что я должен сделать вместо этого?Имеет ли Java функцию «выборки», как в R?



Уточнение : при выборке без замены я имею в виду взять в случайном порядке 15 уникальныхэлементы из 30 доступны в исходном списке.Более того, я хочу иметь возможность делать это неоднократно.

Ответы [ 4 ]

10 голосов
/ 23 января 2012

Используйте метод Collections#shuffle, чтобы перетасовать исходный список и вернуть список с первыми 15 элементами.

2 голосов
/ 23 января 2012

Рассмотрите возможность создания нового списка и добавления случайных элементов из текущего списка вместо копирования всех элементов и их удаления.

Другой способ сделать это - создать какой-то View поверх текущего списка.

Реализация интерфейса Iterator, который случайным образом генерирует индекс элемента во время операции next и извлекает элемент по индексу из текущего списка.

1 голос
/ 23 января 2012

Нет, в 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 в цикле).

0 голосов
/ 23 января 2012

Это основная проблема комбинаторики. В вашем списке 30 элементов, и вы хотите выбрать 15. Если порядок имеет значение, вы хотите перестановку, если не важно, вам нужна комбинация.

В Интернете есть различные примеры комбинаторики Java, и они обычно используют combinadics . Я не знаю ни одной готовой библиотеки Java, но Apache Math Commons имеет поддержку биномиальных коэффициентов, чтобы помочь вам реализовать комбинатику, если вы пойдете по этому пути. Если у вас есть последовательность из 15 индексов от 0 до 29, я бы предложил создать итератор только для чтения, из которого вы можете читать элементы. Таким образом, вам не нужно будет создавать новые списки или копировать ссылки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...