All Downloads are FREE. Search and download functionalities are using the official Maven repository.

smile.util.PriorityQueue Maven / Gradle / Ivy

/*******************************************************************************
 * Copyright (c) 2010-2020 Haifeng Li. All rights reserved.
 *
 * Smile is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of
 * the License, or (at your option) any later version.
 *
 * Smile is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Smile.  If not, see .
 ******************************************************************************/

package smile.util;

/**
 * Priority Queue for index items.
 *
 * @author Haifeng Li
 */
public class PriorityQueue {

    /**
     * The number of items in the queue.
     */
    private int n;
    /**
     * The d-ary heap or d-heap is a generalization of the binary heap data
     * structure whose non-leaf nodes have d children, instead of 2. Thus,
     * a binary heap is a 2-heap.
     */
    private int d;
    /**
     * External array of priority.
     */
    private double[] a;
    /**
     * The array of item indices.
     */
    private int[] pq;
    /**
     * The inverse array qp allows the priority-queue to treat the array indices
     * as handles.
     */
    private int[] qp;

    /**
     * Priority comparison of item i and j.
     * @param i item index
     * @param j item index
     */
    private boolean less(int i, int j) {
        return a[pq[i]] < a[pq[j]];
    }

    /**
     * Swap i and j items of pq and qp.
     * @param i item index
     * @param j item index
     */
    private void swap(int i, int j) {
        int t = pq[i];
        pq[i] = pq[j];
        pq[j] = t;
        qp[pq[i]] = i;
        qp[pq[j]] = j;
    }

    /**
     * fix up.
     */
    private void swim(int k) {
        while (k > 1 && less(k, (k + d - 2) / d)) {
            swap(k, (k + d - 2) / d);
            k = (k + d - 2) / d;
        }
    }

    /**
     * fix down.
     */
    private void sink(int k, int N) {
        int j;
        while ((j = d * (k - 1) + 2) <= N) {
            for (int i = j + 1; i < j + d && i <= N; i++) {
                if (less(i, j)) {
                    j = i;
                }
            }
            if (!(less(j, k))) {
                break;
            }
            swap(k, j);
            k = j;
        }
    }

    /**
     * Constructor. Default use a 3-heap.
     * @param a external array of priority. Lower value means higher priority.
     */
    public PriorityQueue(double[] a) {
        this(3, a);
    }

    /**
     * Constructor.
     * @param d d-heap.
     * @param a external array of priority. Lower value means higher priority.
     */
    public PriorityQueue(int d, double[] a) {
        this.d = d;
        this.a = a;
        this.n = 0;
        pq = new int[a.length + 1];
        qp = new int[a.length + 1];
    }

    /**
     * Returns true if the queue is empty.
     */
    public boolean empty() {
        return n == 0;
    }

    /**
     * Insert a new item into queue.
     * @param v the index of item.
     */
    public void insert(int v) {
        pq[++n] = v;
        qp[v] = n;
        swim(n);
    }

    /**
     * Removes and returns the index of item with minimum value (highest priority).
     */
    public int poll() {
        swap(1, n);
        sink(1, n - 1);
        return pq[n--];
    }

    /**
     * The value of item k is lower (higher priority) now.
     */
    public void lower(int k) {
        swim(qp[k]);
    }

    /**
     * The priority of item k has changed.
     */
    public void change(int k) {
        swim(qp[k]);
        sink(qp[k], n);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy