/* This program 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. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.opentripplanner.common.pqueue; import java.util.ArrayList; import java.util.List; import java.util.PriorityQueue; import junit.framework.TestCase; /* * Test correctness and relative speed of various * priority queue implementations. */ public class TestPQueues extends TestCase { private static final int N = 50000; public void doQueue(BinHeap<Integer> q, List<Integer> input, List<Integer> expected) { List<Integer> result = new ArrayList<Integer>(N); int expectedSum = 0; for (Integer i : input) { q.insert(i, i * 0.5); expectedSum += i; } while (!q.empty()) { result.add(q.extract_min()); } assertEquals(result, expected); // check behavior when queue is empty assertEquals(q.size(), 0); assertNull(q.peek_min()); assertNull(q.extract_min()); q.insert(100, 10); q.insert(200, 20); assertEquals(q.size(), 2); assertNotNull(q.extract_min()); assertNotNull(q.extract_min()); assertNull(q.extract_min()); assertEquals(q.size(), 0); // fill and empty the queue a few times int sum = 0; for (Integer i : input) q.insert(i, i); while (!q.empty()) sum += q.extract_min(); // keep compiler from optimizing out extract assertTrue(sum == expectedSum); } public void fillQueue(BinHeap<Integer> q, List<Integer> input) { for (Integer i : input) { q.insert(i, i * 0.5); } int sum = 0; for (Integer j : input) { sum += q.extract_min(); q.insert(j, j * 0.5); } while (!q.empty()) { sum += q.extract_min(); } // keep compiler from optimizing out extract assertTrue(sum != 0); } public void testCompareHeaps() throws InterruptedException { List<Integer> input, expected; input = new ArrayList<Integer>(N); for (int i=0; i<N; i++) input.add((int) (Math.random() * 10000)); // First determine the expected results using a plain old PriorityQueue expected = new ArrayList<Integer>(N); PriorityQueue<Integer> q = new PriorityQueue<Integer>(N); for (Integer j : input) { q.add(j); } while (!q.isEmpty()) { expected.add(q.remove()); } doQueue(new BinHeap<Integer>(), input, expected); fillQueue(new BinHeap<Integer>(), input); } /* * You must be careful to produce unique objects for rekeying, * otherwise the same object might be rekeyed twice or more. */ public void testRekey() throws InterruptedException { final int N = 5000; final int ITER = 2; List<Double> keys; List<Integer> vals; keys = new ArrayList<Double>(N); vals = new ArrayList<Integer>(N); BinHeap<Integer> bh = new BinHeap<Integer>(20); for (int iter = 0; iter < ITER; iter++) { // reuse internal array in binheap bh.reset(); // fill both keys and values with random numbers for (int i=0; i<N; i++) { keys.add(i, (Math.random() * 10000)); vals.add(i, (N - i) * 3); } // insert them into the queue for (int i=0; i<N; i++) { bh.insert(vals.get(i), keys.get(i)); } // requeue every item with a new key that is an // order-preserving function of its place in the original list for (int i=0; i<N; i++) { bh.rekey(vals.get(i), i * 2.0D + 10); // bh.dump(); } // pull everything out of the queue in order // and check that the order matches the original list for (int i=0; i<N; i++) { Double qp = bh.peek_min_key(); Integer qi = bh.extract_min(); assertEquals(qi, vals.get(i)); } // the queue should be empty at the end of each iteration assertTrue(bh.empty()); } } }