priority example java list size priority-queue

example - Prioridad de JavaQueue con tamaño fijo



priority queue python (7)

MinMaxPriorityQueue , Google Guava

De hecho, existe una clase para mantener una cola que, al agregar un elemento que excede el tamaño máximo de la colección, compara los elementos para encontrar un elemento para eliminar y, por lo tanto, crear espacio: MinMaxPriorityQueue encontrado en Google Guava a partir de la versión 8.

EvictingQueue

Por cierto, si simplemente quiere eliminar el elemento más antiguo sin hacer ninguna comparación de los valores de los objetos, Google Guava 15 ganó la clase EvictingQueue .

Estoy calculando una gran cantidad de posibles combinaciones resultantes de algortihm. Para ordenar estas combinaciones, las califico con un valor doble y las almaceno en PriorityQueue. Actualmente, hay cerca de 200k elementos en esa cola, que es prácticamente una memoria intesiva. En realidad, solo necesito, digamos, los mejores 1000 o 100 de todos los elementos de la lista. Entonces comencé a preguntarme si hay una manera de tener una cola de prioridad con un tamaño fijo en Java. Debería comportarme así: ¿el artículo es mejor que uno de los ya almacenados? En caso afirmativo, insértelo en la posición correspondiente y arroje el elemento con la menor calificación.

¿Alguien tiene alguna idea? Muchas gracias de nuevo!

Marco



Parece natural simplemente mantener los primeros 1000 cada vez que agregue un elemento, pero PriorityQueue no ofrece nada para lograrlo con elegancia. Tal vez puedas, en lugar de utilizar PriorityQueue , hacer algo como esto en un método:

List<Double> list = new ArrayList<Double>(); ... list.add(newOutput); Collections.sort(list); list = list.subList(0, 1000);


Solo poll() la cola si su elemento menos es menor que (en su caso, tiene una clasificación peor que) el elemento actual.

static <V extends Comparable<? super V>> PriorityQueue<V> nbest(int n, Iterable<V> valueGenerator) { PriorityQueue<V> values = new PriorityQueue<V>(); for (V value : valueGenerator) { if (values.size() == n && value.compareTo(values.peek()) > 0) values.poll(); // remove least element, current is better if (values.size() < n) // we removed one or haven''t filled up, so add values.add(value); } return values; }

Esto supone que tiene algún tipo de combinación de clase que implementa Comparable que compara combinaciones en su calificación.

Editar: solo para aclarar, el Iterable en mi ejemplo no necesita ser rellenado previamente. Por ejemplo, aquí hay un Iterable<Integer> que le dará todos los números naturales que un int puede representar:

Iterable<Integer> naturals = new Iterable<Integer>() { public Iterator<Integer> iterator() { return new Iterator<Integer>() { int current = 0; @Override public boolean hasNext() { return current >= 0; } @Override public Integer next() { return current++; } @Override public void remove() { throw new UnsupportedOperationException(); } }; } };

El consumo de memoria es muy modesto, como puede ver, para más de 2 mil millones de valores, necesita dos objetos (el Iterable y el Iterator ) más uno int .

Por supuesto, puedes adaptar mi código con bastante facilidad para que no use un Iterable ; simplemente lo usé porque es una forma elegante de representar una secuencia (también, he estado haciendo demasiado Python y C # ☺).


Un mejor enfoque sería moderar más estrechamente lo que pasa en la cola, eliminarlo y anexarlo a medida que se ejecuta el programa. Parece que habría espacio para excluir algunos elementos antes de agregarlos a la cola. Sería más simple que reinventar la rueda, por así decirlo.


Utilice SortedSet:

SortedSet<Item> items = new TreeSet<Item>(new Comparator<Item>(...)); ... void addItem(Item newItem) { if (items.size() > 100) { Item lowest = items.first(); if (newItem.greaterThan(lowest)) { items.remove(lowest); } } items.add(newItem); }


que.add(d); if (que.size() > YOUR_LIMIT) que.poll();

¿O entendí mal tu pregunta?

editar: se olvidó de mencionar que para que esto funcione probablemente tengas que invertir tu función comparTo ya que tirará la que tiene la más alta prioridad en cada ciclo. (si a es "mejor" b compare (a, b) debe devolver un número positivo.

ejemplo para mantener los números más grandes usan algo como esto:

public int compare(Double first, Double second) { // keep the biggest values return first > second ? 1 : -1; }