Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java优先级队列更新问题_Java - Fatal编程技术网

java优先级队列更新问题

java优先级队列更新问题,java,Java,(抱歉我的英语不好)我正在写一个Dijkstra算法的实现,我需要使用优先级队列。 我使用Java平台SE 6中定义的PriorityQueue。 Java平台SE 5中有一种方法,如Q.update()可以在插入元素后其优先级发生变化的情况下重建优先级队列?(我对relax和Q.poll()有问题) 我需要更新采用O(log n)否,使用优先级队列,当元素在队列中时,无法重新堆元素 这是堆的常见优化。尽管移除堆顶并将(更新的)元素放回堆中的时间复杂度是相同的,仅通知堆顶部元素已更新并且可能需要

(抱歉我的英语不好)我正在写一个Dijkstra算法的实现,我需要使用优先级队列。 我使用Java平台SE 6中定义的PriorityQueue。 Java平台SE 5中有一种方法,如Q.update()可以在插入元素后其优先级发生变化的情况下重建优先级队列?(我对relax和Q.poll()有问题)
我需要更新采用O(log n)

否,使用
优先级队列
,当元素在队列中时,无法重新堆元素


这是堆的常见优化。尽管移除堆顶并将(更新的)元素放回堆中的时间复杂度是相同的,仅通知堆顶部元素已更新并且可能需要在堆中向下移动,大约需要一半的时间。

更新优先级队列中已存在的元素的优先级是一项重要操作,不提供此操作的优先级队列或多或少是无用的

优先级队列的实现允许在O(log n)时间内更新已插入的值如下所示:

/**
 * PriorityQueue with updatePriority and item concept.
 * Makes use of a min heap.
 * 
 * @author Chris Stamm 
 * @version 6.10.2013
 */

import java.util.*;

public class PQueue<E extends Comparable<E>> {
public static class PQItem<E extends Comparable<E>> implements Comparable<PQItem<E>> {
    private E m_data;
    private int m_index;

    public PQItem(E data, int index) {
        m_data = data;
        m_index = index;
    }

    public int compareTo(PQItem<E> item) {
        return m_data.compareTo(item.m_data);
    }

    public E getData() {
        return m_data;
    }

    public void setIndex(int index) {
        m_index = index;
    }

    public int getIndex() {
        return m_index;
    }
}

private ArrayList<PQItem<E>> m_array;

public PQueue() {
    m_array = new ArrayList<PQItem<E>>();
}

/**
 * O(n)
 */
public PQueue(Collection<? extends E> c) {
    m_array = new ArrayList<PQItem<E>>(c.size());

    // copy elements
    int j = 0;
    for(E e: c) {
        m_array.add(new PQItem(e, j++));
    }

    // create heap
    final int s = m_array.size();
    int l2 = s/2 - 1;
    for (int i = l2; i >= 0; i--) {
        siftDown(i);
    }
}

public int size() {
    return m_array.size();
}

public boolean isEmpty() {
    return m_array.isEmpty();
}

/**
 * O(log n)
 */
public PQItem<E> add(E data) {
    int s = size();
    PQItem<E> item = new PQItem(data, s);
    m_array.add(item);
    siftUp(s);
    return item;
}

/**
 * O(log n)
 */
public E removeFirst() {
    int size = size();
    if (size == 0) return null;
    if (size == 1) return m_array.remove(0).getData();

    int last = size - 1;
    // swap a[first] with a[last]
    PQItem<E> t = m_array.get(0); 
    E data = t.getData();
    set(0, m_array.get(last)); 
    set(last, t);
    // remove last
    m_array.remove(last);
    // heapify
    siftDown(0);
    return data;
}

public void clear() {
    m_array.clear();
}

public PQItem<E> getItem(int i) {
    return (i >= 0 && i < size()) ? m_array.get(i) : null;
}

public PQItem<E> getFirstItem() {
    return getItem(0);
}

public PQItem<E> getNextItem(PQItem<E> item) {
    if (item == null) return null;
    int index = item.getIndex() + 1;
    return (index < size()) ? m_array.get(index) : null;
}

/**
 * O(log n)
 */
public void updatePriority(PQItem<E> item) {
    int pos = item.getIndex();
    if (pos > 0) {
        // check heap condition at parent
        int par = (pos - 1)/2;
        if (m_array.get(par).compareTo(m_array.get(pos)) > 0) {
            siftUp(pos);
            return;
        }
    }
    int son = pos*2 + 1;
    if (son < size()) {
        // check heap condition at son
        if (m_array.get(pos).compareTo(m_array.get(son)) > 0) {
            siftDown(pos);
        }        
    }
}

private int set(int pos, PQItem<E> item) {
    int oldIndex = item.getIndex();
    item.setIndex(pos);
    m_array.set(pos, item);
    return oldIndex;
}

/**
 * sift down at position pos.
 * O(log n)
 */
private void siftDown(int pos) {
    final int end = size() - 1;
    int son = pos*2 + 1;

    while (son <= end) {
        // son ist der linke Sohn
        if (son < end) {
            // pos hat auch einen rechten Sohn
            if (m_array.get(son).compareTo(m_array.get(son + 1)) > 0) son++;
        }
        // son ist der grössere Sohn
        if (m_array.get(pos).compareTo(m_array.get(son)) > 0) {
            // swap a[pos] with a[son]
            PQItem<E> t = m_array.get(pos); 
            set(pos, m_array.get(son)); 
            set(son, t);
            pos = son;
            son = 2*pos + 1;
        } else {
            return;
        }
    }
}

/**
 * sift up at position pos
 * O(log n)
 */
private void siftUp(int pos) {
    int par = (pos - 1)/2; // parent

    while(par >= 0) {
        if (m_array.get(par).compareTo(m_array.get(pos)) > 0) {
            // swap a[par] with a[pos]
            PQItem<E> t = m_array.get(par); 
            set(par, m_array.get(pos)); 
            set(pos, t);
            pos = par;
            par = (pos - 1)/2;
        } else {
            return;
        }            
    }
}
}
/**
*具有updatePriority和item概念的PriorityQueue。
*使用最小堆。
* 
*@作者克里斯·斯塔姆
*@version 6.10.2013
*/
导入java.util.*;
公开课{
公共静态类PQItem实现可比较{
私人电子货币单位数据;
私有整数m_指数;
公共PQE项目(E数据、int索引){
m_data=数据;
m_指数=指数;
}
公共内部比较(PQItem){
返回m_数据.compareTo(item.m_数据);
}
公共E getData(){
返回m_数据;
}
公共void集合索引(int索引){
m_指数=指数;
}
public int getIndex(){
返回m_指数;
}
}
私有数组列表m_数组;
公共PQUE(){
m_array=new ArrayList();
}
/**
*O(n)
*/

public PQUE(CollectionPriority queue)优先级队列的要点是项目的优先级不应更改。如果更改,则应将其拉出,并以新的优先级重新插入。您有什么可能需要某个有界运行时的要求?我严重怀疑您能否获得O(logN)对于重建队列…您将幸运地得到O(N)可能的重复问题是,当我必须放松时,我必须删除要更改优先级(权重)的元素,更新权重,然后读取此元素Q.remove(v);v.setWeight(u.retWeight()+weight);Q.add(v);我认为Q.remove(v)以O(n)@davy为例-是的,我理解这个问题。不幸的是,内置的
PriorityQueue
没有提供解决方法,这太糟糕了,因为这是堆的一个非常常见的用例。方法
remove()
add()
都是O(logn)。而如果您只使用
peek()
(这是O(1))还有一个
update()
(应该是O(logn),速度是原来的两倍。
static void showMinHeap() {
    Integer[] values = { 7, 9, 6, 3, 5, 1, 2, 8, 4, 0};
    PQueue<Integer> pq = new PQueue<Integer>(Arrays.asList(values));

    int lev = 1, i = 0;
    PQueue.PQItem<Integer> item = pq.getFirstItem();
    while(item != null) {
        if (i == lev) {
            System.out.println();
            lev <<= 1;
            i = 0;
        }
        System.out.print(item.getData());
        System.out.print(' ');
        i++;
        item = pq.getNextItem(item);
    }    
    System.out.println();
}

static void heapSort() {
    Integer[] values = { 7, 9, 6, 3, 5, 1, 2, 8, 4, 0};
    PQueue<Integer> pq = new PQueue<Integer>(Arrays.asList(values));

    for(int i=0; i < values.length; i++) {
        System.out.print(pq.removeFirst());
        System.out.print(' ');
    }
    System.out.println();
}

static void testNodes() {
    class Node implements Comparable<Node> {
        private int m_key;

        public Node(int k) { 
            m_key = k; 
        }

        public void updateKey() {
            m_key *= 2;
        }

        public int compareTo(Node v) {
            return (m_key == v.m_key) ? 0 : (m_key < v.m_key) ? -1 : 1;
        }

        public String toString() {
            return String.valueOf(m_key);
        }
    }

    PQueue<Node> pq= new PQueue<Node>();
    Random rand = new Random(7777);
    final int size = 20;

    for (int i = 0; i < size; i++) {
        Node v = new Node(rand.nextInt(size));
        pq.add(v);
    }
    for (int i = 0; i < size; i++) {
        // change key and update priority
        PQueue.PQItem<Node> item = pq.getItem(rand.nextInt(pq.size()));
        item.getData().updateKey();
        pq.updatePriority(item);

        // remove and show first
        System.out.println(pq.removeFirst());
    }
    System.out.println();
}