`
grunt1223
  • 浏览: 423244 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Java PriorityQueue with fixed size

阅读更多
这个问题来源于StackOverFlow:
http://stackoverflow.com/questions/1846225/java-priorityqueue-with-fixed-size

为方便各位阅读,我把楼主的问题贴出来:

引用

Hi folks,

I am calculating a large number of possible resulting combinations of an algortihm. To sort this combinations I rate them with a double value und store them in PriorityQueue. Currently, there are about 200k items in that queue which is pretty much memory intesive. Acutally, I only need lets say the best 1000 or 100 of all items in the list. So I just started to ask myself if there is a way to have a priority queue with a fixed size in Java. I should behave like this: Is the item better than one of the allready stored? If yes, insert it to the according position and throw the element with the least rating away.

Does anyone have an idea? Thanks very much again!

Marco


令人大跌眼镜的Best Answer居然是:
List<Double> list = new ArrayList<Double>();
...
list.add(newOutput);
Collections.sort(list);
list = list.subList(0, 1000);


这种方法没有从根本上解决内存消耗的问题,绝对是Performence Killer。

正巧,这位朋友遇到的问题我这之前在做图像搜索时也遇到类似的问题。图片识别引擎会将匹配到的每一张图片都打上分数,越高说明相似度越大;最后输出的时候可能只需要其中的前十张就可以了。

先看一下wiki上关于优先级队列的定义:
引用

A priority queue is an abstract data type in computer programming.It is exactly like a regular queue or stack data structure, but additionally, each element is associated with a "priority".
  • stack: elements are pulled in last-in first-out-order (e.g. a stack of papers)
  • queue: elements are pulled in first-come first-served-order (e.g. a line in a cafeteria)
  • priority queue: elements are pulled highest-priority-first (e.g. cutting in line, or VIP service).



一个标准的优先级队列至少要实现以下操作:
  • insertWithPriority: add an element to the queue with an associated priority
  • pullHighestPriorityElement: remove the element from the queue that has the highest priority, and return it


为Priority Queue添加指定的容量限制,就是发帖这位朋友所要的Sized Priority Queue
JDK1.6将优先级队列也加入了Collection中,但是很遗憾,没有提供Sized Priority Queue,我的实现如下:

import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;

public class SizedPriorityQueue<T> {
	private int mSize;
	private boolean mGetLowest = true;
	private LinkedList<T> mList;
	private LinkedList<Double> mPriorities;
	private Comparator<T> mComparator;
	
	/**
	 * Creates a fixed size priority queue that only tracks N values
	 *  
	 * @param size - The maximum number of values to store
	 * @param getLowest - false means to track the highest N values, 
	 * 						true means to track the lowest N values
	 */
	public SizedPriorityQueue(int size, boolean getLowest) {
		mSize = size;
		mGetLowest = getLowest;
		mList = new LinkedList<T>();
		mPriorities = new LinkedList<Double>();
	}
	
	/**
	 * Creates a fixed size priority queue with an explicit comparator for the
	 * class that you want to track. This can be handy if the generic class you
	 * have doesn't implement {@link Comparable}
	 * 
	 * @param size - The maximum number of values to store
	 * @param getLowest - false means to track the highest N values, 
	 * 						true means to track the lowest N values
	 * @param comparator - Explicit comparator for the classyou are tracking
	 */
	public SizedPriorityQueue(int size, boolean getLowest, Comparator<T> comparator) {
		this(size,getLowest);
		mComparator = comparator;
	}
	
	/**
	 * Add a value to the current list of items, it will be inserted into the
	 * correct position in the list if it has a higher priority than the other
	 * items, otherwise it will be dropped
	 * 
	 * @param value
	 */
	public void add(T value){
		if ( mComparator == null ) throw new RuntimeException("Trying to use priority queue default add without comparator defined");
		int index = 0;
		for ( T val : mList ){
			//int comparison = val.compareTo(value);
			int comparison = mComparator.compare(val,value);
			if ( mGetLowest && comparison < 0 ) break;
			if ( !mGetLowest && comparison > 0 ) break;
			index++;
		}
		
		if ( index < mSize - 1)
			mList.add(index,value);
		
		if ( mList.size() > mSize ) mList.removeLast();
	}
	
	/**
	 * Add a value to the current list of items, it will be inserted into the
	 * correct position in the list if it has a higher priority than the other
	 * items, otherwise it will be dropped
	 * 
	 * @param value
	 */
	public void add(T value, double priority){
		int index = 0;

		for ( double val : mPriorities ){
			double comparison = priority - val;
			
			if ( mGetLowest && comparison < 0 ) break;
			if ( !mGetLowest && comparison > 0 ) break;
			index++;
		}
		
		if ( index < mSize - 1) {
			mList.add(index,value);
			mPriorities.add(index,priority);
		}
		
		if ( mList.size() > mSize ){
			mList.removeLast();
			mPriorities.removeLast();
		}
	}
	
	/**
	 * Like any ohter queue, it returns the top 
	 * @return
	 */
	public T pop(){
		if ( mPriorities.size() > 0 )
			mPriorities.pop();
		return mList.pop();
	}
	
	/**
	 * Just returns the top in the list, doesn't remove it
	 * 
	 * @return
	 */
	public T poll(){
		return mList.peek();
	}
	
	/**
	 * @return The size of current list
	 */
	public int size(){
		return mList.size();
	}
	
	/**
	 * Returns an ordered list of all of the scores currently held
	 * 
	 * @return
	 */
	public List<T> getAllScores(){
		return mList;
	}
	
	public static void main(String args[]){
		int numScores = 10;
		int numTopScores = 5;
		Random r = new Random(2);
		SizedPriorityQueue<Integer> queue = new SizedPriorityQueue<Integer>(numTopScores,false);
		for ( int i = 0; i < numScores; i++ ){
			double score = r.nextDouble();
			System.out.println("inserting score: " + score + ", number " + i);
			queue.add(i,score);
		}
		
		while ( queue.size() > 0 ){
			System.out.println(queue.pop());
		}
	}
}


我想,应该会对有如此需求的朋友带来一些帮助吧
3
0
分享到:
评论

相关推荐

    JAVA:PriorityQueue

    ### Java中的PriorityQueue详解 #### 类概述 `PriorityQueue`是Java集合框架的一部分,它是一个基于优先级堆的无界优先级队列。这个队列的元素可以按照它们的自然顺序或者是通过构造队列时提供的`Comparator`进行...

    java优先队列PriorityQueue中Comparator的用法详解

    在Java编程中,`PriorityQueue` 是一个基于优先堆的无界队列。它按照特定的顺序(默认是最小优先顺序)来处理元素,允许快速访问队列头部的最小元素。当我们需要自定义排序规则时,可以使用`Comparator`接口。本文将...

    Java优先队列(PriorityQueue)示例Java

    Java的优先队列(PriorityQueue)是Java集合框架中一个重要的数据结构,它是一个基于堆实现的无界队列。优先队列中的元素按照优先级排序,最高的优先级元素总是在队列的头部。在Java中,PriorityQueue类位于`java....

    解析Java中PriorityQueue优先级队列结构的源码及用法

    Java中的PriorityQueue是一种特殊的队列,它遵循优先级原则,即队列中的元素根据其优先级进行排列。PriorityQueue在JDK中内置,基于二叉堆数据结构实现,特别是最小堆,这意味着队列头部的元素总是具有最低的优先级...

    java集合-PriorityQueue的使用

    PriorityQueue是Java中的一个优先级队列,它可以根据元素的优先级对元素进行排序,并且允许高效地获取和删除最高优先级的元素。

    Lists_Stack_Queue_PriorityQueue.java

    在Java编程语言中,`Lists`, `Stack`, `Queue`, 和 `PriorityQueue` 是四个重要的数据结构,它们各自在不同的场景下发挥着关键作用。这些数据结构是Java集合框架的一部分,帮助开发者有效地组织和操作数据。 1. **...

    基于java优先队列(PriorityQueue)的多路排序算法(含代码)

    在Java编程中,优先队列(PriorityQueue)是一种特殊的队列,它按照元素的优先级进行出队。这种数据结构在实现多路归并排序(Multi-Merge Sort)时非常有用,因为它能有效地处理多个已排序的输入流,并将它们合并成...

    优先队列-java可以选择属性和升序降序

    Java中的`java.util.PriorityQueue`类为我们提供了实现优先队列的功能。 首先,让我们深入理解`PriorityQueue`的基本概念。`PriorityQueue`是基于二叉堆(一种自平衡的树形数据结构)实现的,它不保证队列的顺序,...

    data structures with java

    Java的`java.util.PriorityQueue`实现了最小堆。 9. **排序算法**:如冒泡排序、选择排序、插入排序、快速排序、归并排序和堆排序等,这些算法在实际编程中广泛使用。 10. **查找算法**:如顺序查找、二分查找、...

    Java的优先队列PriorityQueue原理及实例分析

    Java 的优先队列 PriorityQueue 原理及实例分析 Java 的优先队列 PriorityQueue 是 Queue 接口的实现,可以对其中元素进行排序,可以放基本数据类型的包装类(如:Integer,Long 等)或自定义的类。PriorityQueue ...

    Java~三种重写compare方法的PriorityQueue、TopK问题的解决思想附练习题(查找最小的K对数字与最后一块石头重量)

    在Java编程中,`PriorityQueue` 是一个基于优先级堆实现的队列,通常用于处理具有优先级的任务。默认情况下,`PriorityQueue` 使用的小顶堆结构,即队首元素总是最小的。然而,在某些场景下,我们可能需要构建一个大...

    PriorityQueue:使用 O(LogN) 复杂度为测试类实现 PriorityQueue

    优先队列(PriorityQueue)是Java集合框架中的一个重要组件,它提供了一种高效处理具有优先级的数据结构。在Java中,PriorityQueue类实现了Queue接口,它遵循最小堆的原理,即队首元素总是队中最小的(默认情况下)...

    优先级队列头文件priorityqueue.h

    优先级队列头文件priorityqueue.h

    PriorityQueue-MEX-Matlab 优先级队列 matlab

    这个接口可能包括了插入元素(enqueue)、删除最高优先级元素(dequeue)、检查队首元素(peek)以及查询队列大小(size)等基本操作。这样的设计使得在MATLAB中使用优先级队列变得更加便捷和高效。 资源文件夹...

    java 吃水果问题 代码

    在Java编程语言中,"吃水果问题"通常是一个基础的逻辑或算法问题,旨在帮助初学者理解控制流、条件语句、循环等概念。在这个问题中,我们可以假设一个场景:一个人有多种水果,如苹果、香蕉、橙子等,他需要按照特定...

    data structures with java source code

    Java的java.util.PriorityQueue类实现了这个概念,可以用来实现堆排序等算法。 6. **堆(Heap)**:堆是一种特殊的树形数据结构,满足最大堆或最小堆的性质,即父节点的值总是大于或小于其子节点的值。Java的java....

    java工具类 java开发助手 java util

    Java工具类(Java Util)是Java开发中不可或缺的一部分,它为开发者提供了大量便捷的功能,极大地提高了开发效率。在Java标准库中,`java.util`包是核心工具类库,包含了各种容器类、集合框架、日期时间处理、随机数...

    PriorityQueue带优先级的队列md,学习代码笔记

    `PriorityQueue`是Java集合框架中的一种特殊队列,它基于优先堆实现,可以自动对队列中的元素进行排序。与普通队列不同,`PriorityQueue`不是先进先出(FIFO)的数据结构,而是根据元素的自然顺序或者自定义比较器来...

    Java常用工具类大全,工作5年精心整理.zip

    15. **`java.util.PriorityQueue`**:优先队列,内部实现为堆,可以自动维护元素的排序。 以上仅是部分可能包含的工具类,实际压缩包中还可能涵盖其他如并发控制、网络编程、XML处理、加密解密、国际化等更多Java...

    Java集合框架源码剖析:PriorityQueue

     前面以Java ArrayDeque为例讲解了Stack和Queue,其实还有一种特殊的队列叫做PriorityQueue,即优先队列。优先队列的作用是能保证每次取出的元素都是队列中权值小的(Java的优先队列每次取小元素,C++的优先队列...

Global site tag (gtag.js) - Google Analytics