Skip to content

Commit 25beeec

Browse files
committed
Readd removed dp tests
1 parent a415825 commit 25beeec

File tree

1 file changed

+239
-0
lines changed

1 file changed

+239
-0
lines changed

tests/test_dp.py

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
# import math
2+
# import random
3+
import unittest
4+
from typing import Dict
5+
6+
import numpy as np
7+
8+
from exact_kmeans.dynamic_program import compute_bounds
9+
10+
11+
def test_correctness(n: int, k: int, lb: Dict[int, float]) -> bool:
12+
r = compute_bounds(n, k, lb)
13+
opt = bruteforce(n, k, lb)
14+
15+
return bool((opt == r).all()) if r is not None else False
16+
17+
18+
def bruteforce(n: int, k: int, lb: Dict[int, float]) -> np.ndarray:
19+
opt = np.full((n + 1, k + 1), np.inf)
20+
opt[0][0] = 0
21+
bruteforce_enum(n, k, 0, 0, opt, lb)
22+
# print(opt)
23+
return opt
24+
25+
26+
def bruteforce_enum(
27+
n: int, k: int, n_prev: int, k_prev: int, opt: np.ndarray, lb: Dict[int, float]
28+
) -> None:
29+
for i in range(1, n + 1):
30+
n_new = n_prev + i
31+
k_new = k_prev + 1
32+
cost_new = opt[n_prev][k_prev] + lb[i]
33+
if n_new <= n and k_new <= k:
34+
if opt[n_new][k_new] > cost_new:
35+
opt[n_new][k_new] = cost_new
36+
bruteforce_enum(n, k, n_new, k_new, opt, lb)
37+
38+
39+
class TestDynamicProgram(unittest.TestCase):
40+
N_MIN = 10
41+
N_MAX = 50
42+
K_MIN = 2
43+
SLOPE = 10
44+
OFFSET = 5
45+
46+
# def test_random(self) -> None:
47+
# for n in range(self.N_MIN, self.N_MAX):
48+
# for k in range(self.K_MIN, n // 2):
49+
# with self.subTest(msg=f"n={n}, k={k}"):
50+
# lb = {i: 0.0 for i in range(0, n + 1)}
51+
# for i in range(2, n + 1):
52+
# lb[i] = random.uniform(lb[i - 1], 1.6 * (lb[i - 1] + 1))
53+
54+
# # print(lb)
55+
# self.assertTrue(
56+
# test_correctness(n, k, lb),
57+
# (
58+
# f"Random test with n={n}, k={k} failed.\n"
59+
# f"Lower bounds: {lb}"
60+
# ),
61+
# )
62+
63+
# def test_linear_increase(self) -> None:
64+
# for n in range(self.N_MIN, self.N_MAX):
65+
# for k in range(self.K_MIN, n // 2):
66+
# with self.subTest(msg=f"n={n}, k={k}"):
67+
# values = [0.0, 0.0]
68+
# values.extend(
69+
# [self.SLOPE * (i - 1) + self.OFFSET for i in range(2, n + 1)]
70+
# )
71+
# lb = {i: values[i] for i in range(0, n + 1)}
72+
73+
# self.assertTrue(
74+
# test_correctness(n, k, lb),
75+
# (
76+
# f"Linear test with n={n}, k={k}, "
77+
# f"slope={self.SLOPE}, offset={self.OFFSET} failed.\n"
78+
# f"Lower bounds: {lb}"
79+
# ),
80+
# )
81+
82+
# def test_exponential_increase(self) -> None:
83+
# for n in range(self.N_MIN, self.N_MAX):
84+
# for k in range(self.K_MIN, n // 2):
85+
# with self.subTest(msg=f"n={n}, k={k}"):
86+
# values = [0.0, 0.0]
87+
# values.extend([2**i for i in range(n - 1)])
88+
# lb = {i: values[i] for i in range(0, n + 1)}
89+
90+
# self.assertTrue(
91+
# test_correctness(n, k, lb),
92+
# (
93+
# f"Exponential test with n={n}, k={k} failed.\n"
94+
# f"Lower bounds: {lb}"
95+
# ),
96+
# )
97+
98+
# def test_logarithmic_increase(self) -> None:
99+
# for n in range(self.N_MIN, self.N_MAX):
100+
# for k in range(self.K_MIN, n // 2):
101+
# with self.subTest(msg=f"n={n}, k={k}"):
102+
# values = [0.0, 0.0]
103+
# values.extend([math.log(i, 2) + 1 for i in range(2, n + 1)])
104+
# lb = {i: values[i] for i in range(0, n + 1)}
105+
106+
# self.assertTrue(
107+
# test_correctness(n, k, lb),
108+
# (f"Log test with n={n}, k={k} failed.\n" f"Lower bounds: {lb}"),
109+
# )
110+
111+
# def test_linear_exponential(self) -> None:
112+
# for n in range(self.N_MIN, self.N_MAX):
113+
# for k in range(self.K_MIN, n // 2):
114+
# with self.subTest(msg=f"n={n}, k={k}"):
115+
# values = [0.0, 0.0]
116+
# values.extend(
117+
# [
118+
# self.SLOPE * (i - 1) + self.OFFSET
119+
# for i in range(2, (n + 1) // 2)
120+
# ]
121+
# )
122+
# values.extend([2**i for i in range((n + 1) // 2, n + 1)])
123+
# lb = {i: values[i] for i in range(0, n + 1)}
124+
125+
# self.assertTrue(
126+
# test_correctness(n, k, lb),
127+
# (
128+
# f"Linear and exponential test with n={n}, k={k} failed."
129+
# f"\nLower bounds: {lb}"
130+
# ),
131+
# )
132+
133+
# def test_exponential_linear(self) -> None:
134+
# for n in range(self.N_MIN, self.N_MAX):
135+
# for k in range(self.K_MIN, n // 2):
136+
# with self.subTest(msg=f"n={n}, k={k}"):
137+
# values = [0.0, 0.0]
138+
# values.extend([2**i for i in range(2, (n + 1) // 2)])
139+
# values.extend(
140+
# [
141+
# self.SLOPE * (i - 1) + self.OFFSET
142+
# for i in range((n + 1) // 2, n + 1)
143+
# ]
144+
# )
145+
# lb = {i: values[i] for i in range(0, n + 1)}
146+
147+
# self.assertTrue(
148+
# test_correctness(n, k, lb),
149+
# (
150+
# f"Exponential and linear test with n={n}, k={k} failed."
151+
# f"\nLower bounds: {lb}"
152+
# ),
153+
# )
154+
155+
# def test_exponential_logarithmic(self) -> None:
156+
# for n in range(self.N_MIN, self.N_MAX):
157+
# for k in range(self.K_MIN, n // 2):
158+
# with self.subTest(msg=f"n={n}, k={k}"):
159+
# values = [0.0, 0.0]
160+
# values.extend([2**i for i in range(2, (n + 1) // 2)])
161+
# values.extend(
162+
# [math.log(i, 2) + 1 for i in range((n + 1) // 2, n + 1)]
163+
# )
164+
# lb = {i: values[i] for i in range(0, n + 1)}
165+
166+
# self.assertTrue(
167+
# test_correctness(n, k, lb),
168+
# (
169+
# f"Exponential and log test with n={n}, k={k} failed."
170+
# f"\nLower bounds: {lb}"
171+
# ),
172+
# )
173+
174+
# def test_logarithmic_exponential(self) -> None:
175+
# for n in range(self.N_MIN, self.N_MAX):
176+
# for k in range(self.K_MIN, n // 2):
177+
# with self.subTest(msg=f"n={n}, k={k}"):
178+
# values = [0.0, 0.0]
179+
# values.extend([math.log(i, 2) + 1 for i in range(2, (n + 1) // 2)])
180+
# values.extend([2**i for i in range((n + 1) // 2, n + 1)])
181+
# lb = {i: values[i] for i in range(0, n + 1)}
182+
183+
# self.assertTrue(
184+
# test_correctness(n, k, lb),
185+
# (
186+
# f"Log and exponential test with n={n}, k={k} failed."
187+
# f"\nLower bounds: {lb}"
188+
# ),
189+
# )
190+
191+
# def test_linear_logarithmic(self) -> None:
192+
# for n in range(self.N_MIN, self.N_MAX):
193+
# for k in range(self.K_MIN, n // 2):
194+
# with self.subTest(msg=f"n={n}, k={k}"):
195+
# values = [0.0, 0.0]
196+
# values.extend(
197+
# [
198+
# self.SLOPE * (i - 1) + self.OFFSET
199+
# for i in range(2, (n + 1) // 2)
200+
# ]
201+
# )
202+
# values.extend(
203+
# [math.log(i, 2) + 1 for i in range((n + 1) // 2, n + 1)]
204+
# )
205+
# lb = {i: values[i] for i in range(0, n + 1)}
206+
207+
# self.assertTrue(
208+
# test_correctness(n, k, lb),
209+
# (
210+
# f"Linear and log test with n={n}, k={k} failed."
211+
# f"\nLower bounds: {lb}"
212+
# ),
213+
# )
214+
215+
# def test_logarithmic_linear(self) -> None:
216+
# for n in range(self.N_MIN, self.N_MAX):
217+
# for k in range(self.K_MIN, n // 2):
218+
# with self.subTest(msg=f"n={n}, k={k}"):
219+
# values = [0.0, 0.0]
220+
# values.extend([math.log(i, 2) + 1 for i in range(2, (n + 1) // 2)])
221+
# values.extend(
222+
# [
223+
# self.SLOPE * (i - 1) + self.OFFSET
224+
# for i in range((n + 1) // 2, n + 1)
225+
# ]
226+
# )
227+
# lb = {i: values[i] for i in range(0, n + 1)}
228+
229+
# self.assertTrue(
230+
# test_correctness(n, k, lb),
231+
# (
232+
# f"Log and linear test with n={n}, k={k} failed."
233+
# f"\nLower bounds: {lb}"
234+
# ),
235+
# )
236+
237+
238+
if __name__ == "__main__":
239+
unittest.main()

0 commit comments

Comments
 (0)