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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. package org.insa.graphs.algorithm.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,
  92. 11 }));
  93. // Queue with 7 elements.
  94. objects.add(
  95. new TestParameters<>(
  96. Arrays.stream(new int[] { 8, 1, 6, 3, 4, 5, 9 })
  97. .mapToObj(MutableInteger::new).toArray(MutableInteger[]::new),
  98. new int[] { 6, 5, 0, 1, 4, 2, 3 }));
  99. // Queue with 7 elements.
  100. objects.add(
  101. new TestParameters<>(
  102. Arrays.stream(new int[] { 1, 7, 4, 8, 9, 6, 5 })
  103. .mapToObj(MutableInteger::new).toArray(MutableInteger[]::new),
  104. new int[] { 2, 0, 1, 3, 4, 5, 6 }));
  105. // Queue with 13 elements.
  106. objects.add(new TestParameters<>(
  107. Arrays.stream(new int[] { 1, 7, 2, 8, 9, 3, 4, 10, 11, 12, 13, 5, 6 })
  108. .mapToObj(MutableInteger::new).toArray(MutableInteger[]::new),
  109. new int[] { 3, 4, 0, 2, 5, 6, 1, 7, 8, 9, 10, 11, 12 }));
  110. return objects;
  111. }
  112. @Parameter
  113. public TestParameters<MutableInteger> parameters;
  114. // Actual queue.
  115. private PriorityQueue<MutableInteger> queue;
  116. @Before
  117. public void init() {
  118. // Create the range queue
  119. this.queue = createQueue();
  120. for (MutableInteger v: parameters.data) {
  121. this.queue.insert(v);
  122. }
  123. }
  124. @Test
  125. public void testIsEmpty() {
  126. assertEquals(parameters.data.length == 0, this.queue.isEmpty());
  127. }
  128. @Test
  129. public void testSize() {
  130. assertEquals(parameters.data.length, this.queue.size());
  131. }
  132. @Test
  133. public void testInsert() {
  134. PriorityQueue<MutableInteger> queue = createQueue();
  135. int size = 0;
  136. for (MutableInteger x: parameters.data) {
  137. queue.insert(x);
  138. assertEquals(++size, queue.size());
  139. }
  140. assertEquals(parameters.data.length, queue.size());
  141. MutableInteger[] range = Arrays.copyOf(parameters.data, parameters.data.length);
  142. Arrays.sort(range);
  143. for (MutableInteger mi: range) {
  144. assertEquals(mi.get(), queue.deleteMin().value);
  145. assertEquals(--size, queue.size());
  146. }
  147. }
  148. @Test(expected = EmptyPriorityQueueException.class)
  149. public void testEmptyFindMin() {
  150. Assume.assumeTrue(queue.isEmpty());
  151. queue.findMin();
  152. }
  153. @Test
  154. public void testFindMin() {
  155. Assume.assumeFalse(queue.isEmpty());
  156. assertEquals(Collections.min(Arrays.asList(parameters.data)).get(), queue.findMin().get());
  157. }
  158. @Test(expected = EmptyPriorityQueueException.class)
  159. public void testEmptyDeleteMin() {
  160. Assume.assumeTrue(queue.isEmpty());
  161. queue.deleteMin();
  162. }
  163. @Test
  164. public void testDeleteMin() {
  165. int size = parameters.data.length;
  166. assertEquals(size, queue.size());
  167. MutableInteger[] range = Arrays.copyOf(parameters.data, parameters.data.length);
  168. Arrays.sort(range);
  169. for (MutableInteger x: range) {
  170. assertEquals(x, queue.deleteMin());
  171. size -= 1;
  172. assertEquals(size, queue.size());
  173. }
  174. assertEquals(0, queue.size());
  175. assertTrue(queue.isEmpty());
  176. }
  177. @Test(expected = ElementNotFoundException.class)
  178. public void testRemoveEmpty() {
  179. Assume.assumeTrue(queue.isEmpty());
  180. queue.remove(new MutableInteger(0));
  181. }
  182. @Test
  183. public void testRemoveNotFound() {
  184. Assume.assumeFalse(queue.isEmpty());
  185. List<MutableInteger> data = Arrays.asList(parameters.data);
  186. MutableInteger min = new MutableInteger(Collections.min(data).get() - 1),
  187. max = new MutableInteger(Collections.max(data).get() + 1);
  188. try {
  189. queue.remove(min);
  190. fail("Expected exception " + ElementNotFoundException.class.getName());
  191. }
  192. catch (ElementNotFoundException e) {
  193. assertEquals(min, e.getElement());
  194. }
  195. try {
  196. queue.remove(max);
  197. fail("Expected exception " + ElementNotFoundException.class.getName());
  198. }
  199. catch (ElementNotFoundException e) {
  200. assertEquals(max, e.getElement());
  201. }
  202. }
  203. @Test
  204. public void testDeleteThenRemove() {
  205. Assume.assumeFalse(queue.isEmpty());
  206. while (!queue.isEmpty()) {
  207. MutableInteger min = queue.deleteMin();
  208. try {
  209. queue.remove(min);
  210. fail("Expected exception " + ElementNotFoundException.class.getName());
  211. }
  212. catch (ElementNotFoundException e) {
  213. assertEquals(min, e.getElement());
  214. }
  215. }
  216. }
  217. @Test
  218. public void testRemoveTwice() {
  219. Assume.assumeFalse(queue.isEmpty());
  220. for (MutableInteger data: parameters.data) {
  221. PriorityQueue<MutableInteger> copyQueue = this.createQueue(this.queue);
  222. copyQueue.remove(data);
  223. try {
  224. copyQueue.remove(data);
  225. fail("Expected exception " + ElementNotFoundException.class.getName());
  226. }
  227. catch (ElementNotFoundException e) {
  228. assertEquals(data, e.getElement());
  229. }
  230. }
  231. }
  232. @Test
  233. public void testRemove() {
  234. int size1 = queue.size();
  235. for (int i = 0; i < parameters.deleteOrder.length; ++i) {
  236. // Remove from structure
  237. queue.remove(parameters.data[parameters.deleteOrder[i]]);
  238. // Copy the remaining elements
  239. PriorityQueue<MutableInteger> copyTree = createQueue(queue);
  240. // Retrieve all remaining elements in both structures
  241. ArrayList<MutableInteger> remains_in = new ArrayList<>(),
  242. remains_cp = new ArrayList<>();
  243. for (int j = i + 1; j < parameters.deleteOrder.length; ++j) {
  244. remains_in.add(parameters.data[parameters.deleteOrder[j]]);
  245. remains_cp.add(copyTree.deleteMin());
  246. }
  247. Collections.sort(remains_in);
  248. // Check that the copy is now empty, and that both list contains all
  249. // elements.
  250. assertTrue(copyTree.isEmpty());
  251. assertEquals(remains_in, remains_cp);
  252. // Check that the size of the original tree is correct.
  253. assertEquals(--size1, queue.size());
  254. }
  255. assertTrue(queue.isEmpty());
  256. }
  257. @Test
  258. public void testRemoveThenAdd() {
  259. Assume.assumeFalse(queue.isEmpty());
  260. int min = Collections.min(Arrays.asList(parameters.data)).get();
  261. for (MutableInteger mi: parameters.data) {
  262. queue.remove(mi);
  263. assertEquals(parameters.data.length - 1, queue.size());
  264. mi.set(--min);
  265. queue.insert(mi);
  266. assertEquals(parameters.data.length, queue.size());
  267. assertEquals(min, queue.findMin().get());
  268. }
  269. }
  270. }