Skip to content

Commit 6d83933

Browse files
committed
update pytest
1 parent 17e8124 commit 6d83933

27 files changed

+839
-90
lines changed

openbox/core/ea/adaptive_ea_advisor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def __init__(self,
5151
self.last_observations = []
5252

5353
def get_suggestion(self):
54-
if not self.last_suggestions:
54+
while not self.last_suggestions:
5555
self.update_observations(self.last_observations)
5656
self.last_observations = []
5757
self.last_suggestions = self.get_suggestions()

test/acq_optimizer/test_random_configuration_chooser.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,26 +13,41 @@ def test_no_cool_down_chooser_returns_expected_result(self):
1313
self.assertTrue(chooser.check(2))
1414
self.assertFalse(chooser.check(3))
1515

16+
chooser2 = ChooserNoCoolDown(1.0)
17+
self.assertTrue(chooser2.modulus == 1.0)
18+
1619
def test_linear_cool_down_chooser_returns_expected_result(self):
1720
chooser = ChooserLinearCoolDown(2.0, 0.3, np.inf)
1821
self.assertTrue(chooser.check(2))
1922
self.assertFalse(chooser.check(3))
2023

24+
chooser.next_smbo_iteration()
25+
self.assertTrue(chooser.check(3))
26+
2127
def test_prob_chooser_returns_expected_result(self):
2228
chooser = ChooserProb(0.5, self.rng)
2329
self.assertTrue(chooser.check(1))
2430
self.assertFalse(chooser.check(2))
2531

2632
def test_prob_cool_down_chooser_returns_expected_result(self):
27-
chooser = ChooserProbCoolDown(0.5, 0.1, self.rng)
33+
chooser = ChooserProbCoolDown(0.5, 2, self.rng)
2834
self.assertTrue(chooser.check(1))
2935
self.assertFalse(chooser.check(2))
3036

37+
chooser.next_smbo_iteration()
38+
self.assertTrue(chooser.check(3))
39+
3140
def test_cosine_annealing_chooser_returns_expected_result(self):
3241
chooser = ChooserCosineAnnealing(0.5, 0.1, 2, self.rng)
3342
self.assertTrue(chooser.check(1))
3443
self.assertFalse(chooser.check(2))
3544

45+
chooser.next_smbo_iteration()
46+
self.assertTrue(chooser.iteration == 1)
47+
chooser.next_smbo_iteration()
48+
chooser.next_smbo_iteration()
49+
self.assertTrue(chooser.iteration == 0)
50+
3651

3752
if __name__ == '__main__':
3853
unittest.main()

test/acquisition_function/test_acquisition.py

Lines changed: 112 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,15 @@
1212
LCB,
1313
Uncertainty,
1414
)
15-
15+
'''
16+
加入其他函数的测试
17+
'''
18+
from openbox.acquisition_function.multi_objective_acquisition import (
19+
MaxvalueEntropySearch,
20+
MESMO,
21+
MESMOC,
22+
MESMOC2,
23+
)
1624
class ConfigurationMock:
1725
def __init__(self, values=None):
1826
self.values = values
@@ -22,6 +30,13 @@ def get_array(self):
2230
return np.array(self.values, dtype=np.float64)
2331

2432
class MockModel:
33+
'''
34+
其实axis的重点在于方向,而不是行和列。具体到各种用法而言也是如此。
35+
当axis=1时,如果是求平均,那么是从左到右横向求平均;如果是拼接,那么也是左右横向拼接;如果是drop,那么也是横向发生变化,体现为列的减少。
36+
mean_col_vector = np.mean(X, axis=1).reshape(-1, 1)
37+
return mean_col_vector, mean_col_vector
38+
这里代码重复了?
39+
'''
2540
def predict_marginalized_over_instances(self, X):
2641
return np.array([np.mean(X, axis=1).reshape((1, -1))]).reshape((-1, 1)), np.array(
2742
[np.mean(X, axis=1).reshape((1, -1))]
@@ -45,11 +60,30 @@ def __init__(self, num_targets=1):
4560
self.num_targets = num_targets
4661

4762
def predict_marginalized_over_instances(self, X):
63+
'''
64+
这个乘法真的没有问题?不是引用?
65+
np.full(X.shape[0], 0.0):创建一个与 X 的行数相同的全 0 数组。
66+
>>> b=[a]
67+
>>> b
68+
[array([1, 2])]
69+
>>> b*2
70+
[array([1, 2]), array([1, 2])]
71+
>>> c=b*2
72+
>>> c
73+
[array([1, 2]), array([1, 2])]
74+
>>> c[0][0]=2
75+
>>> c
76+
[array([2, 2]), array([2, 2])]
77+
>>>
78+
'''
4879
return np.array([np.mean(X, axis=1).reshape((1, -1))] * self.num_targets).reshape((-1, 2)), np.array(
4980
[np.full(X.shape[0], 0.0).reshape((1, -1))] * self.num_targets
5081
).reshape((-1, 2))
5182

5283
class MockConstraintModel:
84+
'''
85+
np.full(m.shape, 0.1):创建一个与 m 形状相同的数组,数组中的每个元素都为 0.1
86+
'''
5387
def predict_marginalized_over_instances(self, X):
5488
m = -np.abs(np.mean(X, axis=1)).reshape((-1, 1))
5589
v = np.full(m.shape, 0.1)
@@ -60,6 +94,7 @@ def predict_marginalized_over_instances(self, X):
6094
return np.full(X.shape[0], np.nan).reshape((-1, 1)), np.full(X.shape[0], np.nan).reshape((-1, 1))
6195

6296
class MockModelWrongVShape:
97+
#错的v shape?
6398
def predict_marginalized_over_instances(self, X):
6499
m = np.mean(X, axis=1).reshape((-1, 2))
65100
v = np.var(X, axis=1).reshape((-1, 1))
@@ -150,6 +185,12 @@ def test_ei_eta_fail(model, acquisition_function):
150185
ei.update(model=model)
151186
configurations = [ConfigurationMock([1.0])]
152187
with pytest.raises(ValueError):
188+
'''
189+
1. with pytest.raises(ValueError):
190+
pytest.raises 是 pytest 提供的一个上下文管理器,用于检查某段代码是否抛出特定类型的异常。
191+
ValueError 是期望的异常类型。
192+
这段代码的含义是:在 with 语句的块内,pytest 期望执行的代码会引发 ValueError。如果代码没有抛出 ValueError,测试将会失败。
193+
'''
153194
ei(configurations)
154195

155196
def test_ei_1x1(model, acquisition_function):
@@ -426,7 +467,7 @@ def test_pi_1xD(model, acq_pi):
426467
def test_pi_NxD(model, acq_pi):
427468
pi = acq_pi
428469
pi.update(model=model, eta=1.0)
429-
configurations = [
470+
configurations = [
430471
ConfigurationMock([0.0001, 0.0001, 0.0001]),
431472
ConfigurationMock([0.1, 0.1, 0.1]),
432473
ConfigurationMock([1.0, 1.0, 1.0]),
@@ -549,4 +590,72 @@ def test_uncertainty_with_nan(model_with_nan, acq_uncer):
549590
configurations = [ConfigurationMock([0.5])]
550591
acq = uncertainty(configurations)
551592

552-
assert np.all(acq == 0)
593+
assert np.all(acq == 0)
594+
595+
596+
597+
598+
'''
599+
import numpy as np
600+
601+
# 创建一个形状为 (2, 3, 4) 的三维数组
602+
data = np.array([
603+
[[1, 2, 3, 4], # 实验 1
604+
[5, 6, 7, 8],
605+
[9, 10, 11, 12]],
606+
607+
[[13, 14, 15, 16], # 实验 2
608+
[17, 18, 19, 20],
609+
[21, 22, 23, 24]]
610+
])
611+
612+
print("原始数组:")
613+
print(data)
614+
mean_axis_0 = np.mean(data, axis=0)
615+
print("沿 axis=0 计算的均值:")
616+
print(mean_axis_0)
617+
# 输出:
618+
# [[ 7. 8. 9. 10.]
619+
# [11. 12. 13. 14.]
620+
# [15. 16. 17. 18.]]
621+
mean_axis_1 = np.mean(data, axis=1)
622+
623+
print("沿 axis=1 计算的均值:")
624+
print(mean_axis_1)
625+
# 输出:
626+
# [[ 5. 6. 7. 8.]
627+
# [19. 20. 21. 22.]]
628+
629+
mean_axis_neg1 = np.mean(data, axis=-1)
630+
print("沿 axis=-1 计算的均值:")
631+
print(mean_axis_neg1)
632+
# 输出:
633+
# [[ 2.5 6.5 10.5]
634+
# [14.5 18.5 22.5]]
635+
总结
636+
'''
637+
638+
'''
639+
使用 np.expand_dims
640+
当我们调用:
641+
expanded = np.expand_dims(self.cell_lower_bounds, axis=(1, 2))
642+
axis=(1, 2) 指定在第 1 和第 2 维的位置插入新维度。
643+
变化步骤
644+
第一次扩展 (axis=1):
645+
646+
原始数组形状为 (m,),在第 1 维插入一个新维度后,形状变为 (1, m):
647+
python
648+
复制代码
649+
[[1, 2, 3]] # 形状为 (1, 3)
650+
第二次扩展 (axis=2):
651+
652+
在新数组的第 2 维插入新维度,形状变为 (1, m, 1):
653+
python
654+
复制代码
655+
[[[1],
656+
[2],
657+
[3]]] # 形状为 (1, 3, 1)
658+
总结
659+
因此,经过两次扩展后,self.cell_lower_bounds 的形状最终变为 (1, m, 1),表示有一个批次(第一维为 1),m 个目标(第二维为 m),
660+
以及每个目标的单个值(第三维为 1)。这种形状使得该数组可以与其他三维数组(如 Y_samples)进行有效的广播和运算。
661+
'''

test/core/ea/test_adaptive_ea_advisor.py

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@
77

88
def test_adaptive_ea_advisor(configspace_tiny):
99
config_space = configspace_tiny
10-
advisor = AdaptiveEAAdvisor(config_space, population_size=4, subset_size=2, num_objectives=2, pc=1, pm=1)
10+
advisor = AdaptiveEAAdvisor(config_space, population_size=8, subset_size=2, num_objectives=2, pc=1, pm=1)
11+
#换一个oldest策略再来一次?
12+
'''
13+
目前看来这个只支持单目标优化,这里的多目标似乎是假的
14+
'''
15+
advisor_oldest = AdaptiveEAAdvisor(config_space, strategy='oldest', population_size=8, subset_size=2, num_objectives=2, pc=1, pm=1)
1116
assert advisor.config_space == config_space
1217
assert advisor.subset_size == 2
1318
assert advisor.epsilon == 0.2
@@ -20,13 +25,23 @@ def test_adaptive_ea_advisor(configspace_tiny):
2025
assert advisor.k4 == 0.3
2126
assert advisor.last_suggestions == []
2227
assert advisor.last_observations == []
23-
24-
perfs = [[2, 1], [1, 2], [2, 2], [1, 1], [1, 2]]
25-
for i in range(4):
28+
'''
29+
多assert
30+
'''
31+
perfs = [[2, 1], [1, 2], [2, 2], [1, 1], [1, 2], [1, 1], [1, 1], [1, 1], [1, 1], [2, 3], [4, 5], [6, 7], [3, 6]]
32+
#修改为10次 ref_point多给点
33+
for i in range(13):
2634
suggestion1 = advisor.get_suggestion()
2735
assert isinstance(suggestion1, Configuration)
2836
observation1 = Observation(suggestion1, perfs[i], trial_state=SUCCESS, elapsed_time=2.0, extra_info={})
2937
advisor.update_observation(observation1)
38+
'''
39+
oldest strategy
40+
'''
41+
suggestion1 = advisor_oldest.get_suggestion()
42+
assert isinstance(suggestion1, Configuration)
43+
observation1 = Observation(suggestion1, perfs[i], trial_state=SUCCESS, elapsed_time=2.0, extra_info={})
44+
advisor_oldest.update_observation(observation1)
3045

3146
config_a = config_space.sample_configuration()
3247
config_b = config_space.sample_configuration()
@@ -35,4 +50,7 @@ def test_adaptive_ea_advisor(configspace_tiny):
3550

3651
config = config_space.sample_configuration()
3752
next_config = advisor.mutation(config)
38-
assert isinstance(next_config, Configuration)
53+
## 测试None
54+
# config = None
55+
# next_config = advisor.mutation(config)
56+
# assert isinstance(next_config, Configuration)

test/core/ea/test_differential_ea_advisor.py

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,19 @@
66
from openbox.utils.constants import MAXINT, SUCCESS
77

88

9-
def test_cmaes_ea_advisor_initialization(configspace_tiny):
9+
def test_cmaes_ea_advisor_initialization(configspace_tiny, configspace_cat):
1010
config_space = configspace_tiny
1111
advisor = DifferentialEAAdvisor(config_space, num_objectives=2, population_size=4)
12+
config_cat = configspace_cat
13+
#添加变化的f以及cr
14+
15+
'''
16+
在单目标优化中,允许使用动态的 f 和 cr 来提升算法的表现。
17+
在多目标优化中,为了保持多个目标的平衡,限制动态调整 f 和 cr,因此在这种情况下需要固定这些参数。
18+
断言的目的是避免算法在不合适的情况下使用动态参数,确保差分进化算法在不同优化问题上的一致性和正确性。
19+
'''
20+
advisor_vary = DifferentialEAAdvisor(config_space, f=(0,1), cr=(0,1), num_objectives=1, population_size=4)
21+
advisor_cat = DifferentialEAAdvisor(config_cat, num_objectives=1, population_size=4)
1222
assert advisor.config_space == config_space
1323
assert advisor.num_objectives == 2
1424
assert advisor.num_constraints == 0
@@ -24,13 +34,23 @@ def test_cmaes_ea_advisor_initialization(configspace_tiny):
2434
assert advisor.filter_gen_population is None
2535
assert advisor.keep_unexpected_population is True
2636
assert advisor.save_cached_configuration is True
27-
28-
perfs = [[2, 1], [1, 2], [2, 2], [1, 1], [1, 2]]
29-
for i in range(5):
37+
perfs = [[2, 1], [1, 2], [2, 2], [1, 1], [1, 2], [1, 1], [1, 1], [-1, 1]]
38+
for i in range(8):
3039
suggestion1 = advisor.get_suggestion()
3140
assert isinstance(suggestion1, Configuration)
3241
observation1 = Observation(suggestion1, perfs[i], trial_state=SUCCESS, elapsed_time=2.0, extra_info={})
42+
#这个update内有next_population的更新,会把suggestion1也就是gen的config加入sub,让sel能使用sub
3343
advisor.update_observation(observation1)
44+
45+
suggestion2 = advisor_vary.get_suggestion()
46+
assert isinstance(suggestion2, Configuration)
47+
observation2 = Observation(suggestion2, [perfs[i][0]], trial_state=SUCCESS, elapsed_time=2.0, extra_info={})
48+
advisor_vary.update_observation(observation2)
49+
50+
# suggestion3 = advisor_cat.get_suggestion()
51+
# assert isinstance(suggestion3, Configuration)
52+
# observation3 = Observation(suggestion3, [1], trial_state=SUCCESS, elapsed_time=2.0, extra_info={})
53+
# advisor_cat.update_observation(observation3)
3454

3555
config_a = config_space.sample_configuration()
3656
config_b = config_space.sample_configuration()
@@ -40,3 +60,10 @@ def test_cmaes_ea_advisor_initialization(configspace_tiny):
4060

4161
config = advisor.cross_over(config_a, config_b, 0.5)
4262
assert isinstance(config, Configuration)
63+
64+
65+
config_a = config_cat.sample_configuration()
66+
config_b = config_cat.sample_configuration()
67+
config_c = config_cat.sample_configuration()
68+
config = advisor_cat.mutate(config_a, config_b, config_c, 0.5)
69+
#这里的prefs对应ref_point吧?传到Observation中对应objectives属性

test/core/ea/test_nsga2_ea_advisor.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from openbox.utils.constants import MAXINT, SUCCESS
77

88

9-
def test_nsga2_ea_advisor_initialization(configspace_tiny):
9+
def test_nsga2_ea_advisor_initialization(configspace_tiny, configspace_huge):
1010
config_space = configspace_tiny
1111
advisor = NSGA2EAdvisor(config_space, num_objectives=2, subset_size=2, population_size=4)
1212
assert advisor.config_space == config_space
@@ -25,4 +25,18 @@ def test_nsga2_ea_advisor_initialization(configspace_tiny):
2525
suggestion1 = advisor.get_suggestion()
2626
assert isinstance(suggestion1, Configuration)
2727
observation1 = Observation(suggestion1, perfs[i], trial_state=SUCCESS, elapsed_time=2.0, extra_info={})
28-
advisor.update_observation(observation1)
28+
advisor.update_observation(observation1)
29+
30+
obs = list()
31+
for i in range(5):
32+
configs = advisor.get_suggestions()
33+
for config in configs:
34+
obs.append(Observation(config, perfs[i], trial_state=SUCCESS, elapsed_time=2.0, extra_info={}))
35+
advisor.update_observations(obs)
36+
37+
38+
#test cross_over
39+
advisor_2 = NSGA2EAdvisor(config_space=configspace_huge)
40+
for i in range(5):
41+
config = advisor_2.cross_over(configspace_huge.sample_configuration(), configspace_huge.sample_configuration())
42+
assert config.configuration_space == configspace_huge

0 commit comments

Comments
 (0)