2011-12-29 14 views
5

Tengo una PriorityQueue que contiene referencias a algunos objetos. Cuando inicialmente inserto los elementos en la cola de prioridad, el ordenamiento es mantenido por la estructura de datos. Ahora, después de una operación de eliminación, actualizo algunas de las referencias que están siendo retenidas por la cola de prioridad. Idealmente, esto requiere una operación de reheapify en la cola de prioridad, pero como es obvio, ya que estoy modificando las referencias seleccionadas externamente, no se puede desencadenar una reheapify. Entonces, ¿cuál es la mejor manera de asegurar que puedo obtener la ventaja de un montón como máximo de extracción rápida en presencia de modificaciones a elementos arbitrarios dentro de la cola? Veo que necesito una mejor estructura de datos?Reheapify java.util.PriorityQueue después de actualizar los elementos

Para ser más específico, necesito una implementación de algo así como un montón de Fibonacci en Java. http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm ¿Está eso disponible?

+0

Tengo una implementación de un montón Fibonacci en Java si estás interesado. Está disponible en línea en http://www.keithschwarz.com/interesting/code/?dir=fibonacci-heap. ¡Espero eso ayude! – templatetypedef

+0

Incluso los montones de fibonacci no son elásticos frente a los cambios fuera de banda en los pesos de los elementos. Creo que debes eliminar un elemento antes de modificarlo y volver a insertarlo después. –

+0

eliminar un elemento arbitrario del montón requerirá O (n) construcción de montón, supongo. –

Respuesta

2

Puede usar su propio árbol que permita elementos duplicados en lugar de montón. Más fácil, puede usar TreeMap<PriorityKey, LinkedHashSet<Value>>. Todas las operaciones son O (log priorityType):

  • adición es get(priority).add(value), si obtener retornos nula, put(priority, new LinkedHashSet())
  • la eliminación de un elemento arbitrario es similar, excepto necesidades para eliminar la prioridad del mapa si el conjunto es vacío.
  • poll() es

-

Entry<PriorityKey, LinkedHashSet<Value>> e = map.firstEntry(); 
if (e==null) return null; 
Iterator<Value> i = e.getValue().iterator(); 
Value v = i.next(); //must always have at least one element. 
i.remove(); 
if (!i.hasNext()) map.remove(e.getKey()); 
return v; 

Aún si tiene que cambiar la prioridad tiene que quitar y añadir el elemento.

+0

OK ... así que diría que PriorityQueue en Java ni implementa la operación DecreaseKey ni proporciona una forma para que el usuario lo implemente de manera eficiente. –

+0

@iamrohitbanga, encontrar una clave en el montón es O (n), luego puede eliminar/agregar cuál es (log N), de nuevo si necesita acceder a un elemento aleatorio en la cola que sería mejor con un árbol . – bestsss

1

Tal vez un NavigableMap se adapte a sus necesidades: fácil identificación del elemento "más alto" o "más bajo", inserción rápida y tiempo de acceso, y puede actualizar los valores fácilmente.

http://docs.oracle.com/javase/7/docs/api/java/util/NavigableMap.html

TreeMap implementa NavigableMap, y por lo tanto proporciona los/lastEntry métodos firstEntry, y muchos más.

+0

no puede tener elementos duplicados en el mapa y debe ordenarse por prioridad. la solución de usar un árbol (mapa) implica mapear prioridad-> colección.(lo publiqué) – bestsss

Cuestiones relacionadas