google-research
830 строк · 31.4 Кб
1// Copyright 2024 The Google Research Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "mutator.h"
16
17#include <memory>
18#include <random>
19
20#include "definitions.h"
21#include "instruction.pb.h"
22#include "algorithm.h"
23#include "algorithm_test_util.h"
24#include "generator.h"
25#include "generator_test_util.h"
26#include "mutator.pb.h"
27#include "random_generator.h"
28#include "test_util.h"
29#include "gtest/gtest.h"
30
31namespace automl_zero {
32
33using ::std::function; // NOLINT
34using ::std::make_shared; // NOLINT
35using ::std::mt19937; // NOLINT
36using ::std::shared_ptr; // NOLINT
37using ::std::vector; // NOLINT
38using ::testing::Test;
39
40TEST(MutatorTest, Runs) {
41mt19937 bit_gen;
42RandomGenerator rand_gen(&bit_gen);
43Mutator mutator(
44ParseTextFormat<MutationTypeList>(
45"mutation_types: [ "
46" ALTER_PARAM_MUTATION_TYPE, "
47" RANDOMIZE_INSTRUCTION_MUTATION_TYPE, "
48" RANDOMIZE_COMPONENT_FUNCTION_MUTATION_TYPE, "
49" INSERT_INSTRUCTION_MUTATION_TYPE, "
50" TRADE_INSTRUCTION_MUTATION_TYPE, "
51" REMOVE_INSTRUCTION_MUTATION_TYPE "
52"] "),
530.5, // mutate_prob
54{NO_OP, SCALAR_SUM_OP, VECTOR_SUM_OP}, // allowed_setup_ops
55{NO_OP, SCALAR_DIFF_OP, VECTOR_DIFF_OP}, // allowed_predict_ops
56{NO_OP, SCALAR_PRODUCT_OP, VECTOR_PRODUCT_OP}, // allowed_learn_ops
570, 10000, 0, 10000, 0, 10000, // min/max component function sizes
58&bit_gen,
59&rand_gen);
60Generator generator(NO_OP_ALGORITHM, 10, 10, 10, {}, {}, {}, nullptr,
61nullptr);
62shared_ptr<const Algorithm> algorithm =
63make_shared<const Algorithm>(SimpleRandomAlgorithm());
64mutator.Mutate(&algorithm);
65}
66
67TEST(MutatorTest, CoversActions) {
68mt19937 bit_gen;
69RandomGenerator rand_gen(&bit_gen);
70Mutator mutator(
71ParseTextFormat<MutationTypeList>(
72"mutation_types: [ "
73" INSERT_INSTRUCTION_MUTATION_TYPE, "
74" TRADE_INSTRUCTION_MUTATION_TYPE, "
75" REMOVE_INSTRUCTION_MUTATION_TYPE "
76"] "),
771.0, // mutate_prob
78{}, // allowed_setup_ops
79{NO_OP}, // allowed_predict_ops
80{}, // allowed_learn_ops
810, 10000, 0, 10000, 0, 10000, // min/max component function sizes
82&bit_gen,
83&rand_gen);
84const Algorithm algorithm = SimpleRandomAlgorithm();
85const IntegerT original_size = algorithm.predict_.size();
86EXPECT_TRUE(IsEventually(
87function<IntegerT(void)>([&](){
88auto mutated_algorithm = make_shared<const Algorithm>(algorithm);
89mutator.Mutate(&mutated_algorithm);
90return static_cast<IntegerT>(mutated_algorithm->predict_.size());
91}),
92{original_size - 1, original_size, original_size + 1},
93{original_size - 1, original_size, original_size + 1}));
94}
95
96TEST(MutatorTest, RespectsMutateProb) {
97mt19937 bit_gen;
98RandomGenerator rand_gen(&bit_gen);
99Mutator mutator(
100ParseTextFormat<MutationTypeList>(
101"mutation_types: [ "
102" INSERT_INSTRUCTION_MUTATION_TYPE "
103"] "),
1040.5, // mutate_prob
105{}, // allowed_setup_ops
106{NO_OP}, // allowed_predict_ops
107{}, // allowed_learn_ops
1080, 10000, 0, 10000, 0, 10000, // min/max component function sizes
109&bit_gen,
110&rand_gen);
111const Algorithm algorithm = SimpleRandomAlgorithm();
112const IntegerT original_size = algorithm.predict_.size();
113EXPECT_TRUE(IsEventually(
114function<IntegerT(void)>([&](){
115auto mutated_algorithm = make_shared<const Algorithm>(algorithm);
116mutator.Mutate(&mutated_algorithm);
117return static_cast<IntegerT>(mutated_algorithm->predict_.size());
118}),
119{original_size, original_size + 1},
120{original_size, original_size + 1}));
121}
122
123TEST(MutatorTest, InstructionIndexTest) {
124mt19937 bit_gen;
125RandomGenerator rand_gen(&bit_gen);
126Mutator mutator(
127MutationTypeList(), 0.0, {}, {}, {},
1280, 10000, 0, 10000, 0, 10000,
129&bit_gen, &rand_gen);
130EXPECT_TRUE(IsEventually(
131function<InstructionIndexT(void)>(
132[&](){return mutator.InstructionIndex(5);}),
133Range<InstructionIndexT>(0, 5),
134Range<InstructionIndexT>(0, 5)));
135}
136
137TEST(MutatorTest, SetupOpTest) {
138mt19937 bit_gen;
139RandomGenerator rand_gen(&bit_gen);
140Mutator mutator(
141MutationTypeList(), 0.0,
142// allowed_setup_ops
143{NO_OP, SCALAR_SUM_OP, MATRIX_VECTOR_PRODUCT_OP, VECTOR_MEAN_OP},
144{}, // allowed_predict_ops
145{}, // allowed_learn_ops
1460, 10000, 0, 10000, 0, 10000, // min/max component function sizes
147&bit_gen, &rand_gen);
148EXPECT_TRUE(IsEventually(
149function<Op(void)>([&](){
150return mutator.SetupOp();
151}),
152{NO_OP, SCALAR_SUM_OP, MATRIX_VECTOR_PRODUCT_OP, VECTOR_MEAN_OP},
153{NO_OP, SCALAR_SUM_OP, MATRIX_VECTOR_PRODUCT_OP, VECTOR_MEAN_OP}));
154}
155
156TEST(MutatorTest, PredictOpTest) {
157mt19937 bit_gen;
158RandomGenerator rand_gen(&bit_gen);
159Mutator mutator(
160MutationTypeList(), 0.0,
161{}, // allowed_setup_ops
162// allowed_predict_ops
163{NO_OP, SCALAR_SUM_OP, MATRIX_VECTOR_PRODUCT_OP, VECTOR_MEAN_OP},
164{}, // allowed_learn_ops
1650, 10000, 0, 10000, 0, 10000, // min/max component function sizes
166&bit_gen, &rand_gen);
167EXPECT_TRUE(IsEventually(
168function<Op(void)>([&](){
169return mutator.PredictOp();
170}),
171{NO_OP, SCALAR_SUM_OP, MATRIX_VECTOR_PRODUCT_OP, VECTOR_MEAN_OP},
172{NO_OP, SCALAR_SUM_OP, MATRIX_VECTOR_PRODUCT_OP, VECTOR_MEAN_OP}));
173}
174
175TEST(MutatorTest, LearnOpTest) {
176mt19937 bit_gen;
177RandomGenerator rand_gen(&bit_gen);
178Mutator mutator(
179MutationTypeList(), 0.0,
180{}, // allowed_setup_ops
181{}, // allowed_predict_ops
182// allowed_learn_ops
183{NO_OP, SCALAR_SUM_OP, MATRIX_VECTOR_PRODUCT_OP, VECTOR_MEAN_OP},
1840, 10000, 0, 10000, 0, 10000, // min/max component function sizes
185&bit_gen, &rand_gen);
186EXPECT_TRUE(IsEventually(
187function<Op(void)>([&](){
188return mutator.LearnOp();
189}),
190{NO_OP, SCALAR_SUM_OP, MATRIX_VECTOR_PRODUCT_OP, VECTOR_MEAN_OP},
191{NO_OP, SCALAR_SUM_OP, MATRIX_VECTOR_PRODUCT_OP, VECTOR_MEAN_OP}));
192}
193
194TEST(MutatorTest, ComponentFunctionTest_SetupPredictLearn) {
195mt19937 bit_gen;
196RandomGenerator rand_gen(&bit_gen);
197Mutator mutator(
198MutationTypeList(), 0.0,
199{NO_OP, SCALAR_SUM_OP}, // allowed_setup_ops
200{NO_OP, SCALAR_SUM_OP}, // allowed_predict_ops
201{NO_OP, SCALAR_SUM_OP}, // allowed_learn_ops
2020, 10000, 0, 10000, 0, 10000, // min/max component function sizes
203&bit_gen, &rand_gen);
204EXPECT_TRUE(IsEventually(
205function<ComponentFunctionT(void)>([&](){
206return mutator.ComponentFunction();
207}),
208{kSetupComponentFunction, kPredictComponentFunction,
209kLearnComponentFunction},
210{kSetupComponentFunction, kPredictComponentFunction,
211kLearnComponentFunction}));
212}
213
214TEST(MutatorTest, ComponentFunctionTest_Setup) {
215mt19937 bit_gen;
216RandomGenerator rand_gen(&bit_gen);
217Mutator mutator(
218MutationTypeList(), 0.0,
219{NO_OP, SCALAR_SUM_OP}, // allowed_setup_ops
220{}, // allowed_predict_ops
221{}, // allowed_learn_ops
2220, 10000, 0, 10000, 0, 10000, // min/max component function sizes
223&bit_gen, &rand_gen);
224EXPECT_TRUE(IsEventually(
225function<ComponentFunctionT(void)>([&](){
226return mutator.ComponentFunction();
227}),
228{kSetupComponentFunction},
229{kSetupComponentFunction}));
230}
231
232TEST(MutatorTest, ComponentFunctionTest_Predict) {
233mt19937 bit_gen;
234RandomGenerator rand_gen(&bit_gen);
235Mutator mutator(
236MutationTypeList(), 0.0,
237{}, // allowed_setup_ops
238{NO_OP, SCALAR_SUM_OP}, // allowed_predict_ops
239{}, // allowed_learn_ops
2400, 10000, 0, 10000, 0, 10000, // min/max component function sizes
241&bit_gen, &rand_gen);
242EXPECT_TRUE(IsEventually(
243function<ComponentFunctionT(void)>([&](){
244return mutator.ComponentFunction();
245}),
246{kPredictComponentFunction},
247{kPredictComponentFunction}));
248}
249
250TEST(MutatorTest, ComponentFunctionTest_Learn) {
251mt19937 bit_gen;
252RandomGenerator rand_gen(&bit_gen);
253Mutator mutator(
254MutationTypeList(), 0.0,
255{}, // allowed_setup_ops
256{}, // allowed_predict_ops
257{NO_OP, SCALAR_SUM_OP}, // allowed_learn_ops
2580, 10000, 0, 10000, 0, 10000, // min/max component function sizes
259&bit_gen, &rand_gen);
260EXPECT_TRUE(IsEventually(
261function<ComponentFunctionT(void)>([&](){
262return mutator.ComponentFunction();
263}),
264{kLearnComponentFunction},
265{kLearnComponentFunction}));
266}
267
268TEST(MutatorTest, AlterParam) {
269RandomGenerator rand_gen;
270const Algorithm algorithm = SimpleRandomAlgorithm();
271Mutator mutator;
272EXPECT_TRUE(IsEventually(
273function<IntegerT(void)>([&](){
274Algorithm mutated_algorithm = algorithm;
275mutator.AlterParam(&mutated_algorithm);
276return CountDifferentInstructions(mutated_algorithm, algorithm);
277}),
278{0, 1}, {1}));
279EXPECT_TRUE(IsEventually(
280function<IntegerT(void)>([&](){
281Algorithm mutated_algorithm = algorithm;
282mutator.AlterParam(&mutated_algorithm);
283return CountDifferentSetupInstructions(mutated_algorithm, algorithm);
284}),
285{0, 1}, {1}));
286EXPECT_TRUE(IsEventually(
287function<IntegerT(void)>([&](){
288Algorithm mutated_algorithm = algorithm;
289mutator.AlterParam(&mutated_algorithm);
290return CountDifferentPredictInstructions(mutated_algorithm, algorithm);
291}),
292{0, 1}, {1}));
293EXPECT_TRUE(IsEventually(
294function<IntegerT(void)>([&](){
295Algorithm mutated_algorithm = algorithm;
296mutator.AlterParam(&mutated_algorithm);
297return CountDifferentLearnInstructions(mutated_algorithm, algorithm);
298}),
299{0, 1}, {1}));
300}
301
302TEST(MutatorTest, RandomizeInstruction) {
303RandomGenerator rand_gen;
304const Algorithm algorithm = SimpleRandomAlgorithm();
305Mutator mutator;
306EXPECT_TRUE(IsEventually(
307function<IntegerT(void)>([&](){
308Algorithm mutated_algorithm = algorithm;
309mutator.RandomizeInstruction(&mutated_algorithm);
310return CountDifferentInstructions(mutated_algorithm, algorithm);
311}),
312{0, 1}, {1}));
313EXPECT_TRUE(IsEventually(
314function<IntegerT(void)>([&](){
315Algorithm mutated_algorithm = algorithm;
316mutator.RandomizeInstruction(&mutated_algorithm);
317return CountDifferentSetupInstructions(mutated_algorithm, algorithm);
318}),
319{0, 1}, {1}));
320EXPECT_TRUE(IsEventually(
321function<IntegerT(void)>([&](){
322Algorithm mutated_algorithm = algorithm;
323mutator.RandomizeInstruction(&mutated_algorithm);
324return CountDifferentPredictInstructions(mutated_algorithm, algorithm);
325}),
326{0, 1}, {1}));
327EXPECT_TRUE(IsEventually(
328function<IntegerT(void)>([&](){
329Algorithm mutated_algorithm = algorithm;
330mutator.RandomizeInstruction(&mutated_algorithm);
331return CountDifferentLearnInstructions(mutated_algorithm, algorithm);
332}),
333{0, 1}, {1}));
334}
335
336TEST(MutatorTest, RandomizeComponentFunction) {
337RandomGenerator rand_gen;
338const Algorithm algorithm = SimpleRandomAlgorithm();
339Mutator mutator;
340const IntegerT setup_size = algorithm.setup_.size();
341const IntegerT predict_size = algorithm.predict_.size();
342const IntegerT learn_size = algorithm.learn_.size();
343vector<IntegerT> num_instr = {setup_size, predict_size, learn_size};
344const IntegerT max_instructions =
345*max_element(num_instr.begin(), num_instr.end());
346EXPECT_TRUE(IsEventually(
347function<IntegerT(void)>([&](){
348Algorithm mutated_algorithm = algorithm;
349mutator.RandomizeComponentFunction(&mutated_algorithm);
350return CountDifferentInstructions(mutated_algorithm, algorithm);
351}),
352Range<IntegerT>(0, max_instructions + 1), {max_instructions}));
353EXPECT_TRUE(IsEventually(
354function<IntegerT(void)>([&](){
355Algorithm mutated_algorithm = algorithm;
356mutator.RandomizeComponentFunction(&mutated_algorithm);
357return CountDifferentSetupInstructions(mutated_algorithm, algorithm);
358}),
359Range<IntegerT>(0, setup_size + 1),
360{setup_size}));
361EXPECT_TRUE(IsEventually(
362function<IntegerT(void)>([&](){
363Algorithm mutated_algorithm = algorithm;
364mutator.RandomizeComponentFunction(&mutated_algorithm);
365return CountDifferentPredictInstructions(mutated_algorithm, algorithm);
366}),
367Range<IntegerT>(0, predict_size + 1),
368{predict_size}));
369EXPECT_TRUE(IsEventually(
370function<IntegerT(void)>([&](){
371Algorithm mutated_algorithm = algorithm;
372mutator.RandomizeComponentFunction(&mutated_algorithm);
373return CountDifferentLearnInstructions(mutated_algorithm, algorithm);
374}),
375Range<IntegerT>(0, learn_size + 1),
376{learn_size}));
377}
378
379TEST(MutatorTest, IdentityMutationType_WorksCorrectly) {
380mt19937 bit_gen;
381RandomGenerator rand_gen(&bit_gen);
382const Algorithm algorithm = SimpleRandomAlgorithm();
383Mutator mutator(
384ParseTextFormat<MutationTypeList>(
385"mutation_types: [IDENTITY_MUTATION_TYPE] "),
3861.0,
387{NO_OP, SCALAR_SUM_OP}, // allowed_setup_ops
388{NO_OP, SCALAR_SUM_OP}, // allowed_predict_ops
389{NO_OP, SCALAR_SUM_OP}, // allowed_learn_ops
3900, 10000, 0, 10000, 0, 10000, // min/max component function sizes
391&bit_gen, &rand_gen);
392auto mutated_algorithm = make_shared<const Algorithm>(algorithm);
393mutator.Mutate(&mutated_algorithm);
394EXPECT_EQ(*mutated_algorithm, algorithm);
395}
396
397TEST(InsertInstructionMutationTypeTest, CoversComponentFunctions) {
398const Algorithm no_op_algorithm = SimpleRandomAlgorithm();
399mt19937 bit_gen;
400RandomGenerator rand_gen(&bit_gen);
401Mutator mutator(
402ParseTextFormat<MutationTypeList>(
403"mutation_types: [INSERT_INSTRUCTION_MUTATION_TYPE] "),
4041.0, // mutate_prob
405{SCALAR_SUM_OP}, // allowed_setup_ops
406{SCALAR_SUM_OP}, // allowed_predict_ops
407{SCALAR_SUM_OP}, // allowed_learn_ops
4080, 10000, 0, 10000, 0, 10000, // min/max component function sizes
409&bit_gen, &rand_gen);
410EXPECT_TRUE(IsEventually(
411function<IntegerT(void)>([&mutator, no_op_algorithm](){
412auto mutated_algorithm = make_shared<const Algorithm>(no_op_algorithm);
413mutator.Mutate(&mutated_algorithm);
414return DifferentComponentFunction(*mutated_algorithm, no_op_algorithm);
415}),
416{0, 1, 2}, {0, 1, 2}));
417}
418
419TEST(InsertInstructionMutationTypeTest, CoversSetupPositions) {
420const Algorithm no_op_algorithm = SimpleNoOpAlgorithm();
421const IntegerT component_function_size = no_op_algorithm.setup_.size();
422mt19937 bit_gen;
423RandomGenerator rand_gen(&bit_gen);
424Mutator mutator(
425ParseTextFormat<MutationTypeList>(
426"mutation_types: [INSERT_INSTRUCTION_MUTATION_TYPE] "),
4271.0, // mutate_prob
428{SCALAR_SUM_OP}, // allowed_setup_ops
429{}, // allowed_predict_ops
430{}, // allowed_learn_ops
4310, 10000, 0, 10000, 0, 10000, // min/max component function sizes
432&bit_gen, &rand_gen);
433ASSERT_GT(component_function_size, 0);
434EXPECT_TRUE(IsEventually(
435function<IntegerT(void)>([&mutator, no_op_algorithm](){
436auto mutated_algorithm = make_shared<const Algorithm>(no_op_algorithm);
437mutator.Mutate(&mutated_algorithm);
438return ScalarSumOpPosition(mutated_algorithm->setup_);
439}),
440Range<IntegerT>(0, component_function_size + 1),
441Range<IntegerT>(0, component_function_size + 1),
4423));
443}
444
445TEST(InsertInstructionMutationTypeTest, CoversPredictPositions) {
446const Algorithm no_op_algorithm = SimpleNoOpAlgorithm();
447const IntegerT component_function_size = no_op_algorithm.predict_.size();
448mt19937 bit_gen;
449RandomGenerator rand_gen(&bit_gen);
450Mutator mutator(
451ParseTextFormat<MutationTypeList>(
452"mutation_types: [INSERT_INSTRUCTION_MUTATION_TYPE] "),
4531.0, // mutate_prob
454{}, // allowed_setup_ops
455{SCALAR_SUM_OP}, // allowed_predict_ops
456{}, // allowed_learn_ops
4570, 10000, 0, 10000, 0, 10000, // min/max component function sizes
458&bit_gen, &rand_gen);
459ASSERT_GT(component_function_size, 0);
460EXPECT_TRUE(IsEventually(
461function<IntegerT(void)>([&mutator, no_op_algorithm](){
462auto mutated_algorithm = make_shared<const Algorithm>(no_op_algorithm);
463mutator.Mutate(&mutated_algorithm);
464return ScalarSumOpPosition(mutated_algorithm->predict_);
465}),
466Range<IntegerT>(0, component_function_size + 1),
467Range<IntegerT>(0, component_function_size + 1),
4683));
469}
470
471TEST(InsertInstructionMutationTypeTest, CoversLearnPositions) {
472const Algorithm no_op_algorithm = SimpleNoOpAlgorithm();
473const IntegerT component_function_size = no_op_algorithm.learn_.size();
474mt19937 bit_gen;
475RandomGenerator rand_gen(&bit_gen);
476Mutator mutator(
477ParseTextFormat<MutationTypeList>(
478"mutation_types: [INSERT_INSTRUCTION_MUTATION_TYPE] "),
4791.0, // mutate_prob
480{}, // allowed_setup_ops
481{}, // allowed_predict_ops
482{SCALAR_SUM_OP}, // allowed_learn_ops
4830, 10000, 0, 10000, 0, 10000, // min/max component function sizes
484&bit_gen, &rand_gen);
485ASSERT_GT(component_function_size, 0);
486EXPECT_TRUE(IsEventually(
487function<IntegerT(void)>([&mutator, no_op_algorithm](){
488auto mutated_algorithm = make_shared<const Algorithm>(no_op_algorithm);
489mutator.Mutate(&mutated_algorithm);
490return ScalarSumOpPosition(mutated_algorithm->learn_);
491}),
492Range<IntegerT>(0, component_function_size + 1),
493Range<IntegerT>(0, component_function_size + 1),
4943));
495}
496
497TEST(InsertInstructionMutationTypeTest, InsertsWhenUnderMinSize) {
498const Algorithm no_op_algorithm = SimpleNoOpAlgorithm();
499const IntegerT setup_component_function_size = no_op_algorithm.setup_.size();
500const IntegerT predict_component_function_size =
501no_op_algorithm.predict_.size();
502const IntegerT learn_component_function_size = no_op_algorithm.learn_.size();
503mt19937 bit_gen;
504RandomGenerator rand_gen(&bit_gen);
505Mutator mutator(
506ParseTextFormat<MutationTypeList>(
507"mutation_types: [INSERT_INSTRUCTION_MUTATION_TYPE] "),
5081.0, // mutate_prob
509{SCALAR_SUM_OP}, // allowed_setup_ops
510{SCALAR_SUM_OP}, // allowed_predict_ops
511{SCALAR_SUM_OP}, // allowed_learn_ops
512100, 10000, 100, 10000, 100, 10000, // min/max component function sizes
513&bit_gen, &rand_gen);
514auto mutated_algorithm = make_shared<const Algorithm>(no_op_algorithm);
515mutator.Mutate(&mutated_algorithm);
516EXPECT_TRUE(mutated_algorithm->setup_.size() ==
517setup_component_function_size + 1 ||
518mutated_algorithm->predict_.size() ==
519predict_component_function_size + 1 ||
520mutated_algorithm->learn_.size() ==
521learn_component_function_size + 1);
522}
523
524TEST(InsertInstructionMutationTypeTest, DoesNotInsertWhenOverMaxSize) {
525const Algorithm no_op_algorithm = SimpleNoOpAlgorithm();
526mt19937 bit_gen;
527RandomGenerator rand_gen(&bit_gen);
528Mutator mutator(
529ParseTextFormat<MutationTypeList>(
530"mutation_types: [INSERT_INSTRUCTION_MUTATION_TYPE] "),
5311.0, // mutate_prob
532{SCALAR_SUM_OP}, // allowed_setup_ops
533{SCALAR_SUM_OP}, // allowed_predict_ops
534{SCALAR_SUM_OP}, // allowed_learn_ops
5350, 1, 0, 1, 0, 1, // min/max component function sizes
536&bit_gen, &rand_gen);
537auto mutated_algorithm = make_shared<const Algorithm>(no_op_algorithm);
538mutator.Mutate(&mutated_algorithm);
539EXPECT_EQ(*mutated_algorithm, no_op_algorithm);
540}
541
542TEST(InsertInstructionMutationTypeTest, CoversSetupInstructions) {
543const Algorithm empty_algorithm;
544mt19937 bit_gen;
545RandomGenerator rand_gen(&bit_gen);
546Mutator mutator(
547ParseTextFormat<MutationTypeList>(
548"mutation_types: [INSERT_INSTRUCTION_MUTATION_TYPE] "),
5491.0, // mutate_prob
550{SCALAR_SUM_OP, SCALAR_DIFF_OP}, // allowed_setup_ops
551{}, // allowed_predict_ops
552{}, // allowed_learn_ops
5530, 10000, 0, 10000, 0, 10000, // min/max component function sizes
554&bit_gen, &rand_gen);
555EXPECT_TRUE(IsEventually(
556function<IntegerT(void)>([&mutator, empty_algorithm](){
557auto mutated_algorithm = make_shared<const Algorithm>(empty_algorithm);
558mutator.Mutate(&mutated_algorithm);
559if (mutated_algorithm->setup_.size() == 1) {
560return static_cast<IntegerT>(mutated_algorithm->setup_[0]->op_);
561} else {
562return static_cast<IntegerT>(-1);
563}
564}),
565{SCALAR_SUM_OP, SCALAR_DIFF_OP}, {SCALAR_SUM_OP, SCALAR_DIFF_OP}, 3));
566}
567
568TEST(InsertInstructionMutationTypeTest, CoversPredictInstructions) {
569const Algorithm empty_algorithm;
570mt19937 bit_gen;
571RandomGenerator rand_gen(&bit_gen);
572Mutator mutator(
573ParseTextFormat<MutationTypeList>(
574"mutation_types: [INSERT_INSTRUCTION_MUTATION_TYPE] "),
5751.0, // mutate_prob
576{}, // allowed_setup_ops
577{SCALAR_SUM_OP, SCALAR_DIFF_OP}, // allowed_predict_ops
578{}, // allowed_learn_ops
5790, 10000, 0, 10000, 0, 10000, // min/max component function sizes
580&bit_gen, &rand_gen);
581EXPECT_TRUE(IsEventually(
582function<IntegerT(void)>([&mutator, empty_algorithm](){
583auto mutated_algorithm = make_shared<const Algorithm>(empty_algorithm);
584mutator.Mutate(&mutated_algorithm);
585if (mutated_algorithm->predict_.size() == 1) {
586return static_cast<IntegerT>(mutated_algorithm->predict_[0]->op_);
587} else {
588return static_cast<IntegerT>(-1);
589}
590}),
591{SCALAR_SUM_OP, SCALAR_DIFF_OP}, {SCALAR_SUM_OP, SCALAR_DIFF_OP}, 3));
592}
593
594TEST(InsertInstructionMutationTypeTest, CoversLearnInstructions) {
595const Algorithm empty_algorithm;
596mt19937 bit_gen;
597RandomGenerator rand_gen(&bit_gen);
598Mutator mutator(
599ParseTextFormat<MutationTypeList>(
600"mutation_types: [INSERT_INSTRUCTION_MUTATION_TYPE] "),
6011.0, // mutate_prob
602{}, // allowed_setup_ops
603{}, // allowed_predict_ops
604{SCALAR_SUM_OP, SCALAR_DIFF_OP}, // allowed_learn_ops
6050, 10000, 0, 10000, 0, 10000, // min/max component function sizes
606&bit_gen, &rand_gen);
607EXPECT_TRUE(IsEventually(
608function<IntegerT(void)>([&mutator, empty_algorithm](){
609auto mutated_algorithm = make_shared<const Algorithm>(empty_algorithm);
610mutator.Mutate(&mutated_algorithm);
611if (mutated_algorithm->learn_.size() == 1) {
612return static_cast<IntegerT>(mutated_algorithm->learn_[0]->op_);
613} else {
614return static_cast<IntegerT>(-1);
615}
616}),
617{SCALAR_SUM_OP, SCALAR_DIFF_OP}, {SCALAR_SUM_OP, SCALAR_DIFF_OP}, 3));
618}
619
620TEST(RemoveInstructionMutationTypeTest, CoversComponentFunctions) {
621const Algorithm random_algorithm = SimpleRandomAlgorithm();
622mt19937 bit_gen;
623RandomGenerator rand_gen(&bit_gen);
624Mutator mutator(
625ParseTextFormat<MutationTypeList>(
626"mutation_types: [REMOVE_INSTRUCTION_MUTATION_TYPE] "),
6271.0, {NO_OP}, {NO_OP}, {NO_OP},
6280, 10000, 0, 10000, 0, 10000, // min/max component function sizes
629&bit_gen, &rand_gen);
630EXPECT_TRUE(IsEventually(
631function<IntegerT(void)>([&mutator, random_algorithm](){
632auto mutated_algorithm = make_shared<const Algorithm>(random_algorithm);
633mutator.Mutate(&mutated_algorithm);
634return DifferentComponentFunction(*mutated_algorithm, random_algorithm);
635}),
636{0, 1, 2}, {0, 1, 2}, 3));
637}
638
639TEST(RemoveInstructionMutationTypeTest, CoversSetupPositions) {
640const Algorithm algorithm = SimpleIncreasingDataAlgorithm();
641const IntegerT component_function_size = algorithm.setup_.size();
642mt19937 bit_gen;
643RandomGenerator rand_gen(&bit_gen);
644Mutator mutator(
645ParseTextFormat<MutationTypeList>(
646"mutation_types: [REMOVE_INSTRUCTION_MUTATION_TYPE] "),
6471.0, // mutate_prob
648{NO_OP}, // allowed_setup_ops
649{}, // allowed_predict_ops
650{}, // allowed_learn_ops
6510, 10000, 0, 10000, 0, 10000, // min/max component function sizes
652&bit_gen, &rand_gen);
653ASSERT_GT(component_function_size, 0);
654EXPECT_TRUE(IsEventually(
655function<IntegerT(void)>([&mutator, algorithm](){
656auto mutated_algorithm = make_shared<const Algorithm>(algorithm);
657mutator.Mutate(&mutated_algorithm);
658return MissingDataInComponentFunction(
659algorithm.setup_, mutated_algorithm->setup_);
660}),
661Range<IntegerT>(0, component_function_size),
662Range<IntegerT>(0, component_function_size),
6633));
664}
665
666TEST(RemoveInstructionMutationTypeTest, CoversPredictPositions) {
667const Algorithm algorithm = SimpleIncreasingDataAlgorithm();
668const IntegerT component_function_size = algorithm.predict_.size();
669mt19937 bit_gen;
670RandomGenerator rand_gen(&bit_gen);
671Mutator mutator(
672ParseTextFormat<MutationTypeList>(
673"mutation_types: [REMOVE_INSTRUCTION_MUTATION_TYPE] "),
6741.0, // mutate_prob
675{}, // allowed_setup_ops
676{NO_OP}, // allowed_predict_ops
677{}, // allowed_learn_ops
6780, 10000, 0, 10000, 0, 10000, // min/max component function sizes
679&bit_gen, &rand_gen);
680ASSERT_GT(component_function_size, 0);
681EXPECT_TRUE(IsEventually(
682function<IntegerT(void)>([&mutator, algorithm](){
683auto mutated_algorithm = make_shared<const Algorithm>(algorithm);
684mutator.Mutate(&mutated_algorithm);
685return MissingDataInComponentFunction(
686algorithm.predict_, mutated_algorithm->predict_);
687}),
688Range<IntegerT>(0, component_function_size),
689Range<IntegerT>(0, component_function_size),
6903));
691}
692
693TEST(RemoveInstructionMutationTypeTest, CoversLearnPositions) {
694const Algorithm algorithm = SimpleIncreasingDataAlgorithm();
695const IntegerT component_function_size = algorithm.learn_.size();
696mt19937 bit_gen;
697RandomGenerator rand_gen(&bit_gen);
698Mutator mutator(
699ParseTextFormat<MutationTypeList>(
700"mutation_types: [REMOVE_INSTRUCTION_MUTATION_TYPE] "),
7011.0, // mutate_prob
702{}, // allowed_setup_ops
703{}, // allowed_predict_ops
704{NO_OP}, // allowed_learn_ops
7050, 10000, 0, 10000, 0, 10000, // min/max component function sizes
706&bit_gen, &rand_gen);
707ASSERT_GT(component_function_size, 0);
708EXPECT_TRUE(IsEventually(
709function<IntegerT(void)>([&mutator, algorithm](){
710auto mutated_algorithm = make_shared<const Algorithm>(algorithm);
711mutator.Mutate(&mutated_algorithm);
712return MissingDataInComponentFunction(
713algorithm.learn_, mutated_algorithm->learn_);
714}),
715Range<IntegerT>(0, component_function_size),
716Range<IntegerT>(0, component_function_size),
7173));
718}
719
720TEST(RemoveInstructionMutationTypeTest, DoesNotRemoveWhenUnderMinSize) {
721const Algorithm no_op_algorithm = SimpleNoOpAlgorithm();
722mt19937 bit_gen;
723RandomGenerator rand_gen(&bit_gen);
724Mutator mutator(
725ParseTextFormat<MutationTypeList>(
726"mutation_types: [REMOVE_INSTRUCTION_MUTATION_TYPE] "),
7271.0, // mutate_prob
728{SCALAR_SUM_OP}, // allowed_setup_ops
729{SCALAR_SUM_OP}, // allowed_predict_ops
730{SCALAR_SUM_OP}, // allowed_learn_ops
731100, 10000, 100, 10000, 100, 10000, // min/max component function sizes
732&bit_gen, &rand_gen);
733auto mutated_algorithm = make_shared<const Algorithm>(no_op_algorithm);
734mutator.Mutate(&mutated_algorithm);
735EXPECT_EQ(*mutated_algorithm, no_op_algorithm);
736}
737
738TEST(RemoveInstructionMutationTypeTest, RemovesWhenOverMaxSize) {
739const Algorithm no_op_algorithm = SimpleNoOpAlgorithm();
740const IntegerT setup_component_function_size = no_op_algorithm.setup_.size();
741const IntegerT predict_component_function_size =
742no_op_algorithm.predict_.size();
743const IntegerT learn_component_function_size = no_op_algorithm.learn_.size();
744mt19937 bit_gen;
745RandomGenerator rand_gen(&bit_gen);
746Mutator mutator(
747ParseTextFormat<MutationTypeList>(
748"mutation_types: [REMOVE_INSTRUCTION_MUTATION_TYPE] "),
7491.0, // mutate_prob
750{SCALAR_SUM_OP}, // allowed_setup_ops
751{SCALAR_SUM_OP}, // allowed_predict_ops
752{SCALAR_SUM_OP}, // allowed_learn_ops
7530, 1, 0, 1, 0, 1, // min/max component function sizes
754&bit_gen, &rand_gen);
755auto mutated_algorithm = make_shared<const Algorithm>(no_op_algorithm);
756mutator.Mutate(&mutated_algorithm);
757EXPECT_TRUE(mutated_algorithm->setup_.size() ==
758setup_component_function_size - 1 ||
759mutated_algorithm->predict_.size() ==
760predict_component_function_size - 1 ||
761mutated_algorithm->learn_.size() ==
762learn_component_function_size - 1);
763}
764
765TEST(TradeInstructionMutationTypeTest, CoversComponentFunctions) {
766const Algorithm random_algorithm = SimpleRandomAlgorithm();
767mt19937 bit_gen;
768RandomGenerator rand_gen(&bit_gen);
769Mutator mutator(
770ParseTextFormat<MutationTypeList>(
771"mutation_types: [TRADE_INSTRUCTION_MUTATION_TYPE] "),
7721.0, {NO_OP}, {NO_OP}, {NO_OP},
7730, 10000, 0, 10000, 0, 10000, // min/max component function sizes
774&bit_gen, &rand_gen);
775EXPECT_TRUE(IsEventually(
776function<IntegerT(void)>([&mutator, random_algorithm](){
777auto mutated_algorithm = make_shared<const Algorithm>(random_algorithm);
778mutator.Mutate(&mutated_algorithm);
779return DifferentComponentFunction(*mutated_algorithm, random_algorithm);
780}),
781{-1, 0, 1, 2}, {0, 1, 2}, 3));
782}
783
784TEST(TradeInstructionMutationTypeTest, PreservesSizes) {
785const Algorithm random_algorithm = SimpleRandomAlgorithm();
786mt19937 bit_gen;
787RandomGenerator rand_gen(&bit_gen);
788Mutator mutator(
789ParseTextFormat<MutationTypeList>(
790"mutation_types: [TRADE_INSTRUCTION_MUTATION_TYPE] "),
7911.0, {NO_OP}, {NO_OP}, {NO_OP},
7920, 10000, 0, 10000, 0, 10000, // min/max prog. sizes
793&bit_gen, &rand_gen);
794auto mutated_algorithm = make_shared<const Algorithm>(random_algorithm);
795mutator.Mutate(&mutated_algorithm);
796EXPECT_EQ(mutated_algorithm->setup_.size(), random_algorithm.setup_.size());
797EXPECT_EQ(mutated_algorithm->predict_.size(),
798random_algorithm.predict_.size());
799EXPECT_EQ(mutated_algorithm->learn_.size(), random_algorithm.learn_.size());
800}
801
802TEST(MutatorTest, RandomizeAlgorithm) {
803RandomGenerator rand_gen;
804mt19937 bit_gen;
805const Algorithm algorithm = SimpleRandomAlgorithm();
806const IntegerT setup_size = algorithm.setup_.size();
807const IntegerT predict_size = algorithm.predict_.size();
808const IntegerT learn_size = algorithm.learn_.size();
809Mutator mutator(
810ParseTextFormat<MutationTypeList>(
811"mutation_types: [RANDOMIZE_ALGORITHM_MUTATION_TYPE] "),
8121.0,
813{NO_OP, SCALAR_SUM_OP, MATRIX_VECTOR_PRODUCT_OP, VECTOR_MEAN_OP},
814{NO_OP, SCALAR_SUM_OP, MATRIX_VECTOR_PRODUCT_OP, VECTOR_MEAN_OP},
815{NO_OP, SCALAR_SUM_OP, MATRIX_VECTOR_PRODUCT_OP, VECTOR_MEAN_OP},
816setup_size, setup_size + 1,
817predict_size, predict_size + 1,
818learn_size, learn_size + 1,
819&bit_gen, &rand_gen);
820const IntegerT num_instr = setup_size + predict_size + learn_size;
821EXPECT_TRUE(IsEventually(
822function<IntegerT(void)>([&](){
823Algorithm mutated_algorithm = algorithm;
824mutator.RandomizeAlgorithm(&mutated_algorithm);
825return CountDifferentInstructions(mutated_algorithm, algorithm);
826}),
827Range<IntegerT>(0, num_instr + 1), {num_instr}));
828}
829
830} // namespace automl_zero
831