No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

PriorityQueueTest.java 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. package org.insa.algo.utils;
  2. import static org.junit.Assert.assertEquals;
  3. import static org.junit.Assert.assertTrue;
  4. import static org.junit.Assert.fail;
  5. import java.util.ArrayList;
  6. import java.util.Arrays;
  7. import java.util.Collection;
  8. import java.util.Collections;
  9. import java.util.List;
  10. import java.util.stream.IntStream;
  11. import org.junit.Assume;
  12. import org.junit.Before;
  13. import org.junit.Test;
  14. import org.junit.runner.RunWith;
  15. import org.junit.runners.Parameterized;
  16. import org.junit.runners.Parameterized.Parameter;
  17. import org.junit.runners.Parameterized.Parameters;
  18. @RunWith(Parameterized.class)
  19. public abstract class PriorityQueueTest {
  20. /**
  21. * Needs to be implemented by child class to actually provide priority queue
  22. * implementation.
  23. *
  24. * @return A new instance of a PriorityQueue implementation.
  25. */
  26. public abstract PriorityQueue<MutableInteger> createQueue();
  27. /**
  28. * Needs to be implemented by child class to actually provide priority queue
  29. * implementation.
  30. *
  31. * @param queue Queue to copy.
  32. *
  33. * @return Copy of the given queue.
  34. */
  35. public abstract PriorityQueue<MutableInteger> createQueue(PriorityQueue<MutableInteger> queue);
  36. protected static class MutableInteger implements Comparable<MutableInteger> {
  37. // Actual value
  38. private int value;
  39. public MutableInteger(int value) {
  40. this.value = value;
  41. }
  42. /**
  43. * @return The integer value stored inside this MutableInteger.
  44. */
  45. public int get() {
  46. return this.value;
  47. }
  48. /**
  49. * Update the integer value stored inside this MutableInteger.
  50. *
  51. * @param value New value to set.
  52. */
  53. public void set(int value) {
  54. this.value = value;
  55. }
  56. @Override
  57. public int compareTo(MutableInteger other) {
  58. return Integer.compare(this.value, other.value);
  59. }
  60. @Override
  61. public String toString() {
  62. return Integer.toString(get());
  63. }
  64. };
  65. protected static class TestParameters<E extends Comparable<E>> {
  66. // Data to insert
  67. public final E[] data;
  68. public final int[] deleteOrder;
  69. public TestParameters(E[] data, int[] deleteOrder) {
  70. this.data = data;
  71. this.deleteOrder = deleteOrder;
  72. }
  73. };
  74. /**
  75. * Set of parameters.
  76. *
  77. */
  78. @Parameters
  79. public static Collection<Object> data() {
  80. Collection<Object> objects = new ArrayList<>();
  81. // Empty queue
  82. objects.add(new TestParameters<>(new MutableInteger[0], new int[0]));
  83. // Queue with 50 elements from 0 to 49, inserted in order and deleted in order.
  84. objects.add(new TestParameters<>(
  85. IntStream.range(0, 50).mapToObj(MutableInteger::new).toArray(MutableInteger[]::new),
  86. IntStream.range(0, 50).toArray()));
  87. // Queue with 20 elements from 0 to 19, inserted in order, deleted in the given
  88. // order.
  89. objects.add(new TestParameters<>(
  90. IntStream.range(0, 20).mapToObj(MutableInteger::new).toArray(MutableInteger[]::new),
  91. new int[]{ 12, 17, 18, 19, 4, 5, 3, 2, 0, 9, 10, 16, 8, 14, 13, 15, 7, 6, 1, 11 }));
  92. // Queue with 7 elements.
  93. objects.add(
  94. new TestParameters<>(
  95. Arrays.stream(new int[]{ 8, 1, 6, 3, 4, 5, 9 })
  96. .mapToObj(MutableInteger::new).toArray(MutableInteger[]::new),
  97. new int[]{ 6, 5, 0, 1, 4, 2, 3 }));
  98. // Queue with 7 elements.
  99. objects.add(
  100. new TestParameters<>(
  101. Arrays.stream(new int[]{ 1, 7, 4, 8, 9, 6, 5 })
  102. .mapToObj(MutableInteger::new).toArray(MutableInteger[]::new),
  103. new int[]{ 2, 0, 1, 3, 4, 5, 6 }));
  104. // Queue with 13 elements.
  105. objects.add(new TestParameters<>(
  106. Arrays.stream(new int[]{ 1, 7, 2, 8, 9, 3, 4, 10, 11, 12, 13, 5, 6 })
  107. .mapToObj(MutableInteger::new).toArray(MutableInteger[]::new),
  108. new int[]{ 3, 4, 0, 2, 5, 6, 1, 7, 8, 9, 10, 11, 12 }));
  109. return objects;
  110. }
  111. @Parameter
  112. public TestParameters<MutableInteger> parameters;
  113. // Actual queue.
  114. private PriorityQueue<MutableInteger> queue;
  115. @Before
  116. public void init() {
  117. // Create the range queue
  118. this.queue = createQueue();
  119. for (MutableInteger v: parameters.data) {
  120. this.queue.insert(v);
  121. }
  122. }
  123. @Test
  124. public void testIsEmpty() {
  125. assertEquals(parameters.data.length == 0, this.queue.isEmpty());
  126. }
  127. @Test
  128. public void testSize() {
  129. assertEquals(parameters.data.length, this.queue.size());
  130. }
  131. @Test
  132. public void testInsert() {
  133. PriorityQueue<MutableInteger> queue = createQueue();
  134. int size = 0;
  135. for (MutableInteger x: parameters.data) {
  136. queue.insert(x);
  137. assertEquals(++size, queue.size());
  138. }
  139. assertEquals(parameters.data.length, queue.size());
  140. MutableInteger[] range = Arrays.copyOf(parameters.data, parameters.data.length);
  141. Arrays.sort(range);
  142. for (MutableInteger mi: range) {
  143. assertEquals(mi.get(), queue.deleteMin().value);
  144. assertEquals(--size, queue.size());
  145. }
  146. }
  147. @Test(expected = EmptyPriorityQueueException.class)
  148. public void testEmptyFindMin() {
  149. Assume.assumeTrue(queue.isEmpty());
  150. queue.findMin();
  151. }
  152. @Test
  153. public void testFindMin() {
  154. Assume.assumeFalse(queue.isEmpty());
  155. assertEquals(Collections.min(Arrays.asList(parameters.data)).get(), queue.findMin().get());
  156. }
  157. @Test(expected = EmptyPriorityQueueException.class)
  158. public void testEmptyDeleteMin() {
  159. Assume.assumeTrue(queue.isEmpty());
  160. queue.deleteMin();
  161. }
  162. @Test
  163. public void testDeleteMin() {
  164. int size = parameters.data.length;
  165. assertEquals(queue.size(), size);
  166. MutableInteger[] range = Arrays.copyOf(parameters.data, parameters.data.length);
  167. Arrays.sort(range);
  168. for (MutableInteger x: range) {
  169. assertEquals(x, queue.deleteMin());
  170. size -= 1;
  171. assertEquals(size, queue.size());
  172. }
  173. assertEquals(0, queue.size());
  174. assertTrue(queue.isEmpty());
  175. }
  176. @Test(expected = ElementNotFoundException.class)
  177. public void testRemoveEmpty() {
  178. Assume.assumeTrue(queue.isEmpty());
  179. queue.remove(new MutableInteger(0));
  180. }
  181. @Test
  182. public void testRemoveNotFound() {
  183. Assume.assumeFalse(queue.isEmpty());
  184. List<MutableInteger> data = Arrays.asList(parameters.data);
  185. MutableInteger min = new MutableInteger(Collections.min(data).get() - 1),
  186. max = new MutableInteger(Collections.max(data).get() + 1);
  187. try {
  188. queue.remove(min);
  189. fail("Expected exception " + ElementNotFoundException.class.getName());
  190. }
  191. catch (ElementNotFoundException e) {
  192. assertEquals(e.getElement(), min);
  193. }
  194. try {
  195. queue.remove(max);
  196. fail("Expected exception " + ElementNotFoundException.class.getName());
  197. }
  198. catch (ElementNotFoundException e) {
  199. assertEquals(e.getElement(), max);
  200. }
  201. }
  202. @Test
  203. public void testDeleteThenRemove() {
  204. Assume.assumeFalse(queue.isEmpty());
  205. while (!queue.isEmpty()) {
  206. MutableInteger min = queue.deleteMin();
  207. try {
  208. queue.remove(min);
  209. fail("Expected exception " + ElementNotFoundException.class.getName());
  210. }
  211. catch (ElementNotFoundException e) {
  212. assertEquals(e.getElement(), min);
  213. }
  214. }
  215. }
  216. @Test
  217. public void testRemoveTwice() {
  218. Assume.assumeFalse(queue.isEmpty());
  219. for (MutableInteger data: parameters.data) {
  220. PriorityQueue<MutableInteger> copyQueue = this.createQueue(this.queue);
  221. copyQueue.remove(data);
  222. try {
  223. copyQueue.remove(data);
  224. fail("Expected exception " + ElementNotFoundException.class.getName());
  225. }
  226. catch (ElementNotFoundException e) {
  227. assertEquals(e.getElement(), data);
  228. }
  229. }
  230. }
  231. @Test
  232. public void testRemove() {
  233. int size1 = queue.size();
  234. for (int i = 0; i < parameters.deleteOrder.length; ++i) {
  235. // Remove from structure
  236. queue.remove(parameters.data[parameters.deleteOrder[i]]);
  237. // Copy the remaining elements
  238. PriorityQueue<MutableInteger> copyTree = createQueue(queue);
  239. // Retrieve all remaining elements in both structures
  240. ArrayList<MutableInteger> remains_in = new ArrayList<>(),
  241. remains_cp = new ArrayList<>();
  242. for (int j = i + 1; j < parameters.deleteOrder.length; ++j) {
  243. remains_in.add(parameters.data[parameters.deleteOrder[j]]);
  244. remains_cp.add(copyTree.deleteMin());
  245. }
  246. Collections.sort(remains_in);
  247. // Check that the copy is now empty, and that both list contains all
  248. // elements.
  249. assertTrue(copyTree.isEmpty());
  250. assertEquals(remains_in, remains_cp);
  251. // Check that the size of the original tree is correct.
  252. assertEquals(--size1, queue.size());
  253. }
  254. assertTrue(queue.isEmpty());
  255. }
  256. @Test
  257. public void testRemoveThenAdd() {
  258. Assume.assumeFalse(queue.isEmpty());
  259. int min = Collections.min(Arrays.asList(parameters.data)).get();
  260. for (MutableInteger mi: parameters.data) {
  261. queue.remove(mi);
  262. assertEquals(parameters.data.length - 1, queue.size());
  263. mi.set(--min);
  264. queue.insert(mi);
  265. assertEquals(parameters.data.length, queue.size());
  266. assertEquals(min, queue.findMin().get());
  267. }
  268. }
  269. }