test_heaps.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. import pytest
  2. import networkx as nx
  3. from networkx.utils import BinaryHeap, PairingHeap
  4. class X:
  5. def __eq__(self, other):
  6. raise self is other
  7. def __ne__(self, other):
  8. raise self is not other
  9. def __lt__(self, other):
  10. raise TypeError("cannot compare")
  11. def __le__(self, other):
  12. raise TypeError("cannot compare")
  13. def __ge__(self, other):
  14. raise TypeError("cannot compare")
  15. def __gt__(self, other):
  16. raise TypeError("cannot compare")
  17. def __hash__(self):
  18. return hash(id(self))
  19. x = X()
  20. data = [ # min should not invent an element.
  21. ("min", nx.NetworkXError),
  22. # Popping an empty heap should fail.
  23. ("pop", nx.NetworkXError),
  24. # Getting nonexisting elements should return None.
  25. ("get", 0, None),
  26. ("get", x, None),
  27. ("get", None, None),
  28. # Inserting a new key should succeed.
  29. ("insert", x, 1, True),
  30. ("get", x, 1),
  31. ("min", (x, 1)),
  32. # min should not pop the top element.
  33. ("min", (x, 1)),
  34. # Inserting a new key of different type should succeed.
  35. ("insert", 1, -2.0, True),
  36. # int and float values should interop.
  37. ("min", (1, -2.0)),
  38. # pop removes minimum-valued element.
  39. ("insert", 3, -(10**100), True),
  40. ("insert", 4, 5, True),
  41. ("pop", (3, -(10**100))),
  42. ("pop", (1, -2.0)),
  43. # Decrease-insert should succeed.
  44. ("insert", 4, -50, True),
  45. ("insert", 4, -60, False, True),
  46. # Decrease-insert should not create duplicate keys.
  47. ("pop", (4, -60)),
  48. ("pop", (x, 1)),
  49. # Popping all elements should empty the heap.
  50. ("min", nx.NetworkXError),
  51. ("pop", nx.NetworkXError),
  52. # Non-value-changing insert should fail.
  53. ("insert", x, 0, True),
  54. ("insert", x, 0, False, False),
  55. ("min", (x, 0)),
  56. ("insert", x, 0, True, False),
  57. ("min", (x, 0)),
  58. # Failed insert should not create duplicate keys.
  59. ("pop", (x, 0)),
  60. ("pop", nx.NetworkXError),
  61. # Increase-insert should succeed when allowed.
  62. ("insert", None, 0, True),
  63. ("insert", 2, -1, True),
  64. ("min", (2, -1)),
  65. ("insert", 2, 1, True, False),
  66. ("min", (None, 0)),
  67. # Increase-insert should fail when disallowed.
  68. ("insert", None, 2, False, False),
  69. ("min", (None, 0)),
  70. # Failed increase-insert should not create duplicate keys.
  71. ("pop", (None, 0)),
  72. ("pop", (2, 1)),
  73. ("min", nx.NetworkXError),
  74. ("pop", nx.NetworkXError),
  75. ]
  76. def _test_heap_class(cls, *args, **kwargs):
  77. heap = cls(*args, **kwargs)
  78. # Basic behavioral test
  79. for op in data:
  80. if op[-1] is not nx.NetworkXError:
  81. assert op[-1] == getattr(heap, op[0])(*op[1:-1])
  82. else:
  83. pytest.raises(op[-1], getattr(heap, op[0]), *op[1:-1])
  84. # Coverage test.
  85. for i in range(99, -1, -1):
  86. assert heap.insert(i, i)
  87. for i in range(50):
  88. assert heap.pop() == (i, i)
  89. for i in range(100):
  90. assert heap.insert(i, i) == (i < 50)
  91. for i in range(100):
  92. assert not heap.insert(i, i + 1)
  93. for i in range(50):
  94. assert heap.pop() == (i, i)
  95. for i in range(100):
  96. assert heap.insert(i, i + 1) == (i < 50)
  97. for i in range(49):
  98. assert heap.pop() == (i, i + 1)
  99. assert sorted([heap.pop(), heap.pop()]) == [(49, 50), (50, 50)]
  100. for i in range(51, 100):
  101. assert not heap.insert(i, i + 1, True)
  102. for i in range(51, 70):
  103. assert heap.pop() == (i, i + 1)
  104. for i in range(100):
  105. assert heap.insert(i, i)
  106. for i in range(100):
  107. assert heap.pop() == (i, i)
  108. pytest.raises(nx.NetworkXError, heap.pop)
  109. def test_PairingHeap():
  110. _test_heap_class(PairingHeap)
  111. def test_BinaryHeap():
  112. _test_heap_class(BinaryHeap)