tasks_generator 0.5 → 1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: df500fd0b31dd89d245bba5d3c053c85fcce70bc
4
- data.tar.gz: 39b7d2b58aaf8c4cda12f8090c0a87a5e0d34ad5
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NDA0NjJhMmY0YWEzY2VmYzA0M2Q1YjU0MzA4NTNhZWQwNjFiOWNiYg==
5
+ data.tar.gz: !binary |-
6
+ YmJiMTZhYTZlMjQyODk0YmI5ZjM0MmZlOWU2NjE5Y2ExZjM2ZjM5OQ==
5
7
  SHA512:
6
- metadata.gz: e5b154d344d579dfcf2b195cc83c11eaf9ac1388808cc4b1018b394f7db76a64b169e67bfbfc915ee21dac4b86e7e03490e9df6a8d2dfb34bff3e2fc32391e7e
7
- data.tar.gz: 8257965c4b2ef0c80f7680dee458d361a61ab0d89c29cfccdf84754b741fd69781e3e44329d3d52cd85f4ef44462746004c7d4fceaf1c7cf422999d361785f71
8
+ metadata.gz: !binary |-
9
+ MTcyMDk2ZTg5ZTI4NTM3ZmI2ZWU2NzdlNDE3ZTMwNWFhZWI4MzhmNzA2NWU3
10
+ YmY5ZmJjOTMxMjY5NjMzNWQyNzA3YWNlY2VmYzAxMjY5MTljYmIyMDhjNmMx
11
+ OTc5N2NmY2ZiZTk0OTczNjIyNWJhNDAxNWM0OGZlZDZkOGRjY2I=
12
+ data.tar.gz: !binary |-
13
+ MzA4ODU4YzBmMDMzZWJhMWYzZWJmOThkNWYxYjQ5YjVhYmRjZWE5YjhhZjAx
14
+ MDA4OWM1MDc3ZmYxNzFmYjIwNDY0ZjZkMjFlY2EyYWI2NDhiYzdlMTAwNGY1
15
+ OWZlYTE5YTdhMzI2MGU3MGJiOGUyNThjNDYwODU4NTcxYTA0Nzc=
@@ -5,17 +5,18 @@
5
5
  #include "config.h"
6
6
  #include "generator.h"
7
7
  #include "question.h"
8
- #include "theme.h"
8
+ #include "topic.h"
9
9
 
10
- using namespace tasks_generator;
10
+ using namespace ailab;
11
11
 
12
12
  template<>
13
13
  question_t from_ruby<question_t>(Rice::Object obj) {
14
14
  size_t qid = from_ruby<size_t>(obj.call("question_id"));
15
- size_t tid = from_ruby<size_t>(obj.call("theme_id"));
15
+ size_t tid = from_ruby<size_t>(obj.call("topic_id"));
16
16
  size_t d = from_ruby<size_t>(obj.call("difficulty"));
17
+ std::string t = from_ruby<std::string>(obj.call("text"));
17
18
 
18
- return question_t(qid, tid, d);
19
+ return question_t(qid, tid, d, t);
19
20
  }
20
21
 
21
22
  template<>
@@ -45,30 +46,48 @@ Rice::Object to_ruby(std::vector<question_t> const &questions) {
45
46
  }
46
47
 
47
48
  template<>
48
- theme_t from_ruby<theme_t>(Rice::Object obj) {
49
- size_t id = from_ruby<size_t>(obj.call("theme_id"));
50
- size_t dmin = from_ruby<size_t>(obj.call("difficulty_min"));
51
- size_t dmax = from_ruby<size_t>(obj.call("difficulty_max"));
49
+ topic_t from_ruby<topic_t>(Rice::Object obj) {
50
+ size_t id = from_ruby<size_t>(obj.call("topic_id"));
51
+ size_t pid = from_ruby<size_t>(obj.call("parent_id"));
52
+ std::string text = from_ruby<std::string>(obj.call("text"));
52
53
 
53
- return theme_t(id, dmin, dmax);
54
+ return topic_t(id, pid, text);
54
55
  }
55
56
 
56
57
  template<>
57
- Rice::Object to_ruby<theme_t>(theme_t const &th) {
58
- return Rice::Data_Object<theme_t>(new theme_t(th));
58
+ Rice::Object to_ruby<topic_t>(topic_t const &th) {
59
+ return Rice::Data_Object<topic_t>(new topic_t(th));
59
60
  }
60
61
 
61
62
  template<>
62
- std::vector<theme_t> from_ruby<std::vector<theme_t>>(Rice::Object obj) {
63
+ std::vector<topic_t> from_ruby<std::vector<topic_t>>(Rice::Object obj) {
63
64
  Rice::Array arr(obj);
64
65
 
65
- std::vector<theme_t> themes;
66
- themes.reserve(arr.size());
66
+ std::vector<topic_t> topics;
67
+ topics.reserve(arr.size());
67
68
 
68
69
  for (Rice::Object obj : arr)
69
- themes.push_back(from_ruby<theme_t>(obj));
70
+ topics.push_back(from_ruby<topic_t>(obj));
70
71
 
71
- return themes;
72
+ return topics;
73
+ }
74
+
75
+ template<>
76
+ Rice::Object to_ruby<std::vector<size_t>>(std::vector<size_t> const &v) {
77
+ return Rice::Data_Object<std::vector<size_t>>(new std::vector<size_t>(v));
78
+ }
79
+
80
+ template<>
81
+ std::vector<size_t> from_ruby<std::vector<size_t>>(Rice::Object obj) {
82
+ Rice::Array arr(obj);
83
+
84
+ std::vector<size_t> result;
85
+ result.reserve(arr.size());
86
+
87
+ for (Rice::Object obj : arr)
88
+ result.push_back(from_ruby<size_t>(obj));
89
+
90
+ return result;
72
91
  }
73
92
 
74
93
  void set_life_time(Rice::Object obj, size_t life_time) {
@@ -95,25 +114,33 @@ size_t get_population_size(Rice::Object obj) {
95
114
  return Rice::Data_Object<config_t>(obj)->population_size;
96
115
  }
97
116
 
98
- void set_tasks(Rice::Object obj, size_t tasks) {
99
- Rice::Data_Object<config_t>(obj)->tasks = tasks;
117
+ void set_variants_count(Rice::Object obj, size_t variants_count) {
118
+ Rice::Data_Object<config_t>(obj)->variants_count = variants_count;
119
+ }
120
+
121
+ size_t get_variants_count(Rice::Object obj) {
122
+ return Rice::Data_Object<config_t>(obj)->variants_count;
123
+ }
124
+
125
+ void set_questions_count(Rice::Object obj, size_t questions_count) {
126
+ Rice::Data_Object<config_t>(obj)->questions_count = questions_count;
100
127
  }
101
128
 
102
- size_t get_tasks(Rice::Object obj) {
103
- return Rice::Data_Object<config_t>(obj)->tasks;
129
+ size_t get_questions_count(Rice::Object obj) {
130
+ return Rice::Data_Object<config_t>(obj)->questions_count;
104
131
  }
105
132
 
106
- void set_themes(Rice::Object obj, Rice::Array themes) {
107
- std::vector<theme_t> th = from_ruby<std::vector<theme_t>>(themes);
108
- Rice::Data_Object<config_t>(obj)->themes = std::move(th);
133
+ void set_topics(Rice::Object obj, Rice::Array topics) {
134
+ std::vector<size_t> th = from_ruby<std::vector<size_t>>(topics);
135
+ Rice::Data_Object<config_t>(obj)->topics = std::move(th);
109
136
  }
110
137
 
111
- Rice::Array get_themes(Rice::Object obj) {
112
- std::vector<theme_t> const &themes = Rice::Data_Object<config_t>(obj)->themes;
138
+ Rice::Array get_topics(Rice::Object obj) {
139
+ std::vector<size_t> const &topics = Rice::Data_Object<config_t>(obj)->topics;
113
140
 
114
141
  Rice::Array arr;
115
- for (theme_t const &t : themes)
116
- arr.push(to_ruby<theme_t>(t));
142
+ for (size_t t : topics)
143
+ arr.push(to_ruby<size_t>(t));
117
144
 
118
145
  return arr;
119
146
  }
@@ -125,8 +152,9 @@ config_t from_ruby<config_t>(Rice::Object obj) {
125
152
  result.life_time = from_ruby<size_t>(obj.call("life_time"));
126
153
  result.mutation_chance = from_ruby<double>(obj.call("mutation_chance"));
127
154
  result.population_size = from_ruby<size_t>(obj.call("population_size"));
128
- result.tasks = from_ruby<size_t>(obj.call("tasks"));
129
- result.themes = from_ruby<std::vector<theme_t>>(obj.call("themes"));
155
+ result.variants_count = from_ruby<size_t>(obj.call("variants_count"));
156
+ result.questions_count = from_ruby<size_t>(obj.call("questions_count"));
157
+ result.topics = from_ruby<std::vector<size_t>>(obj.call("topics"));
130
158
 
131
159
  return result;
132
160
  }
@@ -139,9 +167,10 @@ Rice::Object to_ruby<config_t>(config_t const &cnf) {
139
167
  template<>
140
168
  generator_t from_ruby<generator_t>(Rice::Object obj) {
141
169
  config_t config = from_ruby<config_t>(obj.call("config"));
170
+ std::vector<topic_t> topics = from_ruby<std::vector<topic_t>>(obj.call("topics"));
142
171
  std::vector<question_t> questions = from_ruby<std::vector<question_t>>(obj.call("questions"));
143
172
 
144
- return generator_t(std::move(config), std::move(questions));
173
+ return generator_t(std::move(config), std::move(topics), std::move(questions));
145
174
  }
146
175
 
147
176
  template<>
@@ -150,9 +179,10 @@ Rice::Object to_ruby(generator_t const &t) {
150
179
  }
151
180
 
152
181
  template<>
153
- Rice::Object to_ruby<generator_t::answer_t>(generator_t::answer_t const &ans) {
182
+ Rice::Object to_ruby<variants_t>(variants_t const &ans) {
183
+ std::vector<std::vector<question_t>> const &questions = ans.get_questions();
154
184
  Rice::Array result;
155
- for (std::vector<question_t> const &arr : ans) {
185
+ for (std::vector<question_t> const &arr : questions) {
156
186
  Rice::Array buffer;
157
187
  for (question_t const &q : arr)
158
188
  buffer.push(to_ruby<question_t>(q));
@@ -165,36 +195,38 @@ extern "C" void Init_tasks_generator() {
165
195
  Rice::Module rb_mTasksGenerator = Rice::define_module("TasksGenerator");
166
196
 
167
197
  Rice::Data_Type<config_t> rb_cConfig = Rice::define_class_under<config_t>(rb_mTasksGenerator, "Config")
168
- .define_constructor(Rice::Constructor<config_t, size_t>(), Rice::Arg("tasks") = 0)
198
+ .define_constructor(Rice::Constructor<config_t, size_t, size_t>(),
199
+ (Rice::Arg("variants_count") = 8, Rice::Arg("questions_count") = 8))
169
200
  .define_method("life_time=", &set_life_time)
170
201
  .define_method("mutation_chance=", &set_mutation_chance)
171
202
  .define_method("population_size=", &set_population_size)
172
- .define_method("tasks=", &set_tasks)
203
+ .define_method("variants_count=", &set_variants_count)
204
+ .define_method("questions_count=", &set_questions_count)
173
205
  .define_method("life_time", &get_life_time)
174
206
  .define_method("mutation_chance", &get_mutation_chance)
175
207
  .define_method("population_size", &get_population_size)
176
- .define_method("tasks", &get_tasks)
177
- .define_method("themes", &get_themes)
178
- .define_method("themes=", &set_themes);
179
-
180
- Rice::Data_Type<theme_t> rb_cTheme = Rice::define_class_under<theme_t>(rb_mTasksGenerator, "Theme")
181
- .define_constructor(Rice::Constructor<theme_t, size_t, size_t, size_t>(),
182
- (Rice::Arg("id"), Rice::Arg("dmin"), Rice::Arg("dmax")))
183
- .define_method("theme_id", &theme_t::get_theme_id)
184
- .define_method("difficulty_min", &theme_t::get_difficulty_min)
185
- .define_method("difficulty_max", &theme_t::get_difficulty_max);
208
+ .define_method("variants_count", &get_variants_count)
209
+ .define_method("questions_count", &get_questions_count)
210
+ .define_method("topics", &get_topics)
211
+ .define_method("topics=", &set_topics);
212
+
213
+ Rice::Data_Type<topic_t> rb_ctopic = Rice::define_class_under<topic_t>(rb_mTasksGenerator, "Topic")
214
+ .define_constructor(Rice::Constructor<topic_t, size_t, size_t, std::string>(),
215
+ (Rice::Arg("id"), Rice::Arg("pid"), Rice::Arg("text")))
216
+ .define_method("topic_id", &topic_t::get_topic_id)
217
+ .define_method("parent_id", &topic_t::get_parent_id)
218
+ .define_method("text", &topic_t::get_text);
186
219
 
187
220
  Rice::Data_Type<question_t> rb_cQuestion = Rice::define_class_under<question_t>(rb_mTasksGenerator, "Question")
188
- .define_constructor(Rice::Constructor<question_t, size_t, size_t, size_t>(),
189
- (Rice::Arg("id"), Rice::Arg("tid"), Rice::Arg("difficulty")))
221
+ .define_constructor(Rice::Constructor<question_t, size_t, size_t, size_t, std::string>(),
222
+ (Rice::Arg("id"), Rice::Arg("tid"), Rice::Arg("difficulty"), Rice::Arg("text")))
190
223
  .define_method("question_id", &question_t::get_question_id)
191
- .define_method("theme_id", &question_t::get_theme_id)
192
- .define_method("difficulty", &question_t::get_difficulty);
224
+ .define_method("topic_id", &question_t::get_topic_id)
225
+ .define_method("difficulty", &question_t::get_difficulty)
226
+ .define_method("text", &question_t::get_text);
193
227
 
194
228
  Rice::Data_Type<generator_t> rb_cGenerator = Rice::define_class_under<generator_t>(rb_mTasksGenerator, "Generator")
195
- .define_constructor(Rice::Constructor<generator_t, config_t, std::vector<question_t>>(),
196
- (Rice::Arg("cnf"), Rice::Arg("questions")))
197
- .define_method("config", &generator_t::get_config)
198
- .define_method("questions", &generator_t::get_questions)
229
+ .define_constructor(Rice::Constructor<generator_t, config_t, std::vector<topic_t>, std::vector<question_t>>(),
230
+ (Rice::Arg("cnf"), Rice::Arg("topics"), Rice::Arg("questions")))
199
231
  .define_method("generate", &generator_t::generate);
200
232
  }
@@ -1,43 +1,79 @@
1
1
  #pragma once
2
2
 
3
- #include "theme.h"
4
- #include "types.h"
3
+ #include <iostream>
4
+ #include <unordered_map>
5
5
 
6
- namespace tasks_generator {
6
+ namespace ailab {
7
7
 
8
8
  struct config_t {
9
9
  size_t life_time;
10
- double mutation_chance;
10
+ size_t try_generate;
11
11
  size_t population_size;
12
+ double mutation_chance;
13
+ double mutation_duplicate_chance;
14
+ bool log_enabled;
15
+ bool stat_enabled;
12
16
 
13
- size_t tasks;
17
+ size_t variants_count;
18
+ size_t questions_count;
14
19
 
15
- std::vector<theme_t> themes;
20
+ std::vector<size_t> topics;
16
21
 
17
- config_t(config_t const &cnf) :
18
- life_time(cnf.life_time),
19
- mutation_chance(cnf.mutation_chance),
20
- population_size(cnf.population_size),
21
- tasks(cnf.tasks),
22
- themes(cnf.themes) {
22
+ config_t(size_t v_count = 8, size_t q_count = 8) noexcept :
23
+ life_time(200),
24
+ try_generate(10),
25
+ population_size(100),
26
+ mutation_chance(0.01),
27
+ mutation_duplicate_chance(0.03),
28
+ log_enabled(false),
29
+ stat_enabled(false),
30
+ variants_count(v_count),
31
+ questions_count(q_count),
32
+ topics() {
23
33
  }
24
34
 
25
- explicit config_t(size_t tasks = 0) :
26
- life_time(1000),
27
- mutation_chance(0.05),
28
- population_size(1000),
29
- tasks(tasks),
30
- themes() {
35
+ config_t(std::unordered_map<std::string, std::string> const &map) noexcept :
36
+ config_t() {
37
+ if (map.find("life-time") != map.end())
38
+ life_time = std::stoul(map.at("life-time"));
39
+ if (map.find("population-size") != map.end())
40
+ population_size = std::stoul(map.at("population-size"));
41
+ if (map.find("mutation-chance") != map.end())
42
+ mutation_chance = std::stod(map.at("mutation-chance"));
43
+ if (map.find("log-enabled") != map.end())
44
+ log_enabled = true;
45
+ if (map.find("variants-count") != map.end())
46
+ variants_count = std::stoul(map.at("variants-count"));
47
+ if (map.find("questions-count") != map.end())
48
+ questions_count = std::stoul(map.at("questions-count"));
49
+ if (map.find("stat-enabled") != map.end())
50
+ stat_enabled = true;
51
+ if (map.find("mutation-duplicate-chance") != map.end())
52
+ mutation_duplicate_chance = std::stod(map.at("mutation-duplicate-chance"));
53
+ if (map.find("try-generate") != map.end())
54
+ try_generate = std::stod(map.at("try-generate"));
31
55
  }
56
+ };
32
57
 
33
- config_t &operator = (config_t const &cnf) {
34
- life_time = cnf.life_time;
35
- mutation_chance = cnf.mutation_chance;
36
- population_size = cnf.population_size;
37
- tasks = cnf.tasks;
38
- themes = cnf.themes;
39
- return *this;
58
+ std::ostream& operator << (std::ostream& out, config_t const &config) {
59
+ out << "config.life_time = " << config.life_time << std::endl;
60
+ out << "config.population_size = " << config.population_size << std::endl;
61
+ out << "config.mutation_chance = " << config.mutation_chance << std::endl;
62
+ out << "config.mutation_duplicate_chance = " << config.mutation_duplicate_chance << std::endl;
63
+ out << "config.log_enabled = " << config.log_enabled << std::endl;
64
+ out << "config.stat_enabled = " << config.stat_enabled << std::endl;
65
+ out << "config.variants_count = " << config.variants_count << std::endl;
66
+ out << "config.questions_count = " << config.questions_count << std::endl;
67
+ out << "config.try_generate = " << config.try_generate << std::endl;
68
+ out << "config.topics = ";
69
+ for (size_t i = 0; i < config.topics.size(); ++i) {
70
+ out << config.topics[i];
71
+ if (i + 1 != config.topics.size())
72
+ out << ", ";
40
73
  }
41
- };
74
+ out << std::endl;
75
+
76
+ return out;
77
+ }
42
78
 
43
79
  }
@@ -1,42 +1,185 @@
1
1
  #pragma once
2
2
 
3
- #include "function.h"
3
+ #include <vector>
4
+
5
+ #include "config.h"
4
6
  #include "question.h"
5
- #include "types.h"
7
+ #include "question_shaker.h"
8
+ #include "topic.h"
9
+ #include "variants.h"
6
10
 
7
- namespace tasks_generator {
11
+ namespace ailab {
8
12
 
9
13
  class generator_t {
14
+ struct stat_t {
15
+ size_t mutations_count;
16
+ size_t mutations_attempts;
17
+ size_t mutation_duplicate_count;
18
+ size_t mutation_duplicate_attempts;
19
+ size_t tried_generate;
20
+ double first_fitness_function;
21
+ double best_fitness_function;
22
+
23
+ stat_t() :
24
+ mutations_count(0),
25
+ mutations_attempts(0),
26
+ mutation_duplicate_count(0),
27
+ mutation_duplicate_attempts(0),
28
+ tried_generate(0),
29
+ first_fitness_function(0),
30
+ best_fitness_function(0) {
31
+ }
32
+ };
33
+
34
+ mutable stat_t stat;
35
+
10
36
  config_t config;
37
+ std::vector<topic_t> topics;
11
38
  std::vector<question_t> questions;
12
39
 
13
- public:
14
- typedef std::vector<std::vector<question_t>> answer_t;
40
+ std::vector<variants_t> generate_population(question_shaker_t const &shaker) const {
41
+ std::vector<variants_t> result;
42
+
43
+ for (size_t k = 0; k < config.population_size; ++k) {
44
+ result.push_back(variants_t(config));
45
+ for (size_t i = 0; i < config.variants_count; ++i) {
46
+ for (size_t j = 0; j < config.questions_count; ++j) {
47
+ size_t r = rand() % config.topics.size();
48
+ result[k][i].push_back(shaker.get_question(config.topics[r]));
49
+ }
50
+ }
51
+ }
15
52
 
16
- generator_t(generator_t const &t) :
17
- config(t.config),
18
- questions(t.questions) {
53
+ return result;
19
54
  }
20
55
 
21
- generator_t(config_t const &config, std::vector<question_t> const &questions) :
22
- config(config),
23
- questions(questions) {
56
+ void crossover(std::vector<variants_t> &population) const noexcept {
57
+ std::sort(population.begin(), population.end(), [] (variants_t const &a, variants_t const &b) -> bool {
58
+ return a.calculate_fitness_function() > b.calculate_fitness_function();
59
+ });
60
+ size_t population_size = population.size();
61
+ for (size_t i = 0; i + 1 < population_size; i += 2)
62
+ population.push_back(population[i].crossover(population[i + 1]));
63
+ for (size_t i = 0; i * 2 < population_size; ++i) {
64
+ size_t r = rand() % (population_size - i) + i;
65
+ population.push_back(population[i].crossover(population[r]));
66
+ }
67
+ }
68
+
69
+ void mutation(std::vector<variants_t> &population, question_shaker_t const &shaker) const {
70
+ size_t population_size = population.size();
71
+ for (size_t i = 0; i < population_size; ++i) {
72
+ bool b = (1 + rand() % 100) <= 100 * config.mutation_duplicate_chance;
73
+ ++stat.mutation_duplicate_attempts;
74
+ if (b) {
75
+ population.push_back(population[i]);
76
+ ++stat.mutation_duplicate_count;
77
+ }
78
+ for (size_t j = 0; j < population[i].size(); ++j)
79
+ for (size_t k = 0; k < population[i][j].size(); ++k) {
80
+ bool b = (1 + rand() % 100) <= 100 * config.mutation_chance;
81
+ ++stat.mutations_attempts;
82
+ if (b) {
83
+ size_t r = rand() % config.topics.size();
84
+ population[i][j][k] = shaker.get_question(config.topics[r]);
85
+ ++stat.mutations_count;
86
+ }
87
+ }
88
+ }
89
+ }
90
+
91
+ void selection(std::vector<variants_t> &population) const noexcept {
92
+ std::sort(population.begin(), population.end(), [] (variants_t const &a, variants_t const &b) -> bool {
93
+ return a.calculate_fitness_function() > b.calculate_fitness_function();
94
+ });
95
+ std::random_shuffle(population.begin() + config.population_size / 2, population.end());
96
+ population.resize(config.population_size + config.population_size / 2);
97
+ }
98
+
99
+ variants_t best(std::vector<variants_t> &population) const noexcept {
100
+ std::sort(population.begin(), population.end(), [] (variants_t const &a, variants_t const &b) -> bool {
101
+ return a.calculate_fitness_function() > b.calculate_fitness_function();
102
+ });
103
+ return population.front();
24
104
  }
25
105
 
26
- generator_t(config_t &&config, std::vector<question_t> &&questions) :
27
- config(config),
28
- questions(std::move(questions)) {
106
+ void strong_mutation(std::vector<variants_t> &population, question_shaker_t const &shaker) const noexcept {
107
+ for (variants_t &v : population)
108
+ v.strong_mutation(shaker);
29
109
  }
30
110
 
31
- config_t get_config() const {
32
- return config;
111
+ bool good_result(variants_t const &v) const noexcept {
112
+ for (size_t i = 0; i < v.size(); ++i) {
113
+ std::unordered_set<size_t> counter;
114
+ for (size_t j = 0; j < v[i].size(); ++j)
115
+ counter.insert(v[i][j].get_question_id());
116
+ if (counter.size() < v[i].size())
117
+ return false;
118
+ }
119
+ return true;
33
120
  }
34
121
 
35
- std::vector<question_t> const &get_questions() const {
36
- return questions;
122
+ public:
123
+ generator_t(config_t const &cnf, std::vector<topic_t> const &topics, std::vector<question_t> const &questions) noexcept :
124
+ config(cnf),
125
+ topics(topics),
126
+ questions(questions) {
127
+ }
128
+
129
+ generator_t(config_t &&cnf, std::vector<topic_t> &&topics, std::vector<question_t> &&questions) noexcept :
130
+ config(cnf),
131
+ topics(topics),
132
+ questions(questions) {
133
+ }
134
+
135
+ generator_t(generator_t const &other) noexcept :
136
+ config(other.config),
137
+ topics(other.topics),
138
+ questions(other.questions) {
37
139
  }
38
140
 
39
- answer_t generate() const;
141
+ variants_t generate() {
142
+ ++stat.tried_generate;
143
+
144
+ question_shaker_t shaker(topics, questions);
145
+ std::vector<variants_t> population = generate_population(shaker);
146
+
147
+ variants_t result = best(population);
148
+ stat.best_fitness_function = stat.first_fitness_function = result.calculate_fitness_function();
149
+
150
+ for (size_t current_time = 1; current_time <= config.life_time; ++current_time) {
151
+ crossover(population);
152
+ selection(population);
153
+ mutation(population, shaker);
154
+ strong_mutation(population, shaker);
155
+
156
+ if (config.log_enabled)
157
+ std::cerr << current_time << '\t' << result.calculate_fitness_function() << std::endl;
158
+
159
+ variants_t buf = best(population);
160
+ if (buf.calculate_fitness_function() > result.calculate_fitness_function()) {
161
+ result = buf;
162
+ stat.best_fitness_function = result.calculate_fitness_function();
163
+ }
164
+ }
165
+
166
+ if (good_result(result) || stat.tried_generate == config.try_generate) {
167
+ if (config.stat_enabled) {
168
+ std::cerr << std::endl;
169
+ std::cerr << "stat.tried_generate = " << stat.tried_generate << std::endl;
170
+ std::cerr << "stat.mutations_attempts = " << stat.mutations_attempts << std::endl;
171
+ std::cerr << "stat.mutations_count = " << stat.mutations_count << std::endl;
172
+ std::cerr << "stat.mutation_duplicate_attempts = " << stat.mutation_duplicate_attempts << std::endl;
173
+ std::cerr << "stat.mutation_duplicate_count = " << stat.mutation_duplicate_count << std::endl;
174
+ std::cerr << "stat.first_fitness_function = " << stat.first_fitness_function << std::endl;
175
+ std::cerr << "stat.best_fitness_function = " << stat.best_fitness_function << std::endl;
176
+ std::cerr << std::endl;
177
+ }
178
+ return result;
179
+ } else {
180
+ return generate();
181
+ }
182
+ }
40
183
  };
41
184
 
42
185
  }
@@ -2,50 +2,42 @@
2
2
 
3
3
  #include <string>
4
4
 
5
- namespace tasks_generator {
5
+ namespace ailab {
6
6
 
7
7
  class question_t {
8
- size_t question_id, theme_id, difficulty;
8
+ size_t question_id, topic_id, difficulty, select_id;
9
+ std::string text;
9
10
 
10
- public:
11
- question_t() :
12
- question_id(0),
13
- theme_id(0),
14
- difficulty(0) {
11
+ public:
12
+ question_t(size_t question_id, size_t topic_id, size_t difficulty, std::string const text = "") noexcept :
13
+ question_id(question_id),
14
+ topic_id(topic_id),
15
+ difficulty(difficulty),
16
+ text(text) {
15
17
  }
16
18
 
17
- question_t(size_t qid, size_t tid, size_t difficulty) :
18
- question_id(qid),
19
- theme_id(tid),
20
- difficulty(difficulty) {
19
+ void set_select_id(size_t x) noexcept {
20
+ select_id = x;
21
21
  }
22
22
 
23
- size_t get_difficulty() const {
24
- return difficulty;
23
+ size_t get_select_id() const noexcept {
24
+ return select_id;
25
25
  }
26
26
 
27
- size_t get_question_id() const {
27
+ size_t get_question_id() const noexcept {
28
28
  return question_id;
29
29
  }
30
30
 
31
- size_t get_theme_id() const {
32
- return theme_id;
33
- }
34
-
35
- bool operator == (question_t const &q) const {
36
- return question_id == q.question_id;
31
+ size_t get_topic_id() const noexcept {
32
+ return topic_id;
37
33
  }
38
34
 
39
- static bool theme_id_cmp(question_t const &a, question_t const &b) {
40
- return a.theme_id < b.theme_id;
41
- }
42
-
43
- static bool difficulty_cmp(question_t const &a, question_t const &b) {
44
- return a.difficulty < b.difficulty;
35
+ size_t get_difficulty() const noexcept {
36
+ return difficulty;
45
37
  }
46
38
 
47
- static bool difficulty_size_t_cmp(question_t const &a, size_t d) {
48
- return a.difficulty < d;
39
+ std::string const &get_text() const noexcept {
40
+ return text;
49
41
  }
50
42
  };
51
43
 
@@ -0,0 +1,62 @@
1
+ #pragma once
2
+
3
+ #include <algorithm>
4
+ #include <cstdlib>
5
+ #include <unordered_map>
6
+ #include <unordered_set>
7
+ #include <vector>
8
+
9
+ #include "topic.h"
10
+ #include "question.h"
11
+
12
+ namespace ailab {
13
+
14
+ // TODO: make it without O(n^2) size
15
+ class question_shaker_t {
16
+ std::unordered_map<size_t, topic_t> topics;
17
+ std::unordered_map<size_t, std::vector<question_t>> questions;
18
+
19
+ void dfs(size_t u, std::unordered_map<size_t, std::vector<size_t>> const &g, std::unordered_set<size_t> &used) noexcept {
20
+ used.insert(u);
21
+ if (g.find(u) == g.end())
22
+ return;
23
+ for (size_t i = 0; i < g.at(u).size(); ++i) {
24
+ size_t v = g.at(u)[i];
25
+ if (used.find(v) == used.end()) {
26
+ dfs(v, g, used);
27
+ for (question_t const &q : questions[v])
28
+ questions[u].push_back(q);
29
+ }
30
+ }
31
+ }
32
+
33
+ public:
34
+ question_shaker_t(std::vector<topic_t> const &t, std::vector<question_t> const &q) noexcept {
35
+ for (question_t const &question : q)
36
+ questions[question.get_topic_id()].push_back(question);
37
+ for (topic_t const &topic : t)
38
+ topics[topic.get_topic_id()] = topic;
39
+ std::unordered_map<size_t, std::vector<size_t>> g;
40
+ std::unordered_set<size_t> used;
41
+ for (topic_t const &topic : t)
42
+ if (topic.get_parent_id() != 0)
43
+ g[topic.get_parent_id()].push_back(topic.get_topic_id());
44
+ for (topic_t const &topic : t)
45
+ if (used.find(topic.get_topic_id()) == used.end())
46
+ dfs(topic.get_topic_id(), g, used);
47
+ for (auto &p : questions)
48
+ std::random_shuffle(p.second.begin(), p.second.end());
49
+ srand(time(0));
50
+ }
51
+
52
+ question_t get_question(size_t topic_id) const {
53
+ if (questions.at(topic_id).empty())
54
+ throw std::logic_error("Not enough questions for topic");
55
+ size_t r = rand() % questions.at(topic_id).size();
56
+ question_t result = questions.at(topic_id)[r];
57
+ result.set_select_id(topic_id);
58
+ return result;
59
+ }
60
+ };
61
+
62
+ }
@@ -0,0 +1,31 @@
1
+ #pragma once
2
+
3
+ #include <string>
4
+
5
+ namespace ailab {
6
+
7
+ class topic_t {
8
+ size_t topic_id, parent_id;
9
+ std::string text;
10
+
11
+ public:
12
+ topic_t(size_t topic_id = 0, size_t parent_id = 0, std::string const &text = "") noexcept :
13
+ topic_id(topic_id),
14
+ parent_id(parent_id),
15
+ text(text) {
16
+ }
17
+
18
+ size_t get_topic_id() const noexcept {
19
+ return topic_id;
20
+ }
21
+
22
+ size_t get_parent_id() const noexcept {
23
+ return parent_id;
24
+ }
25
+
26
+ std::string const &get_text() const noexcept {
27
+ return text;
28
+ }
29
+ };
30
+
31
+ }
@@ -0,0 +1,200 @@
1
+ #pragma once
2
+
3
+ #include <vector>
4
+
5
+ #include "question.h"
6
+
7
+ namespace ailab {
8
+
9
+ class variants_t {
10
+ mutable double fitness;
11
+ mutable bool changed;
12
+
13
+ config_t const &config;
14
+
15
+ size_t questions_count;
16
+ std::vector<std::vector<question_t>> questions;
17
+
18
+ public:
19
+ variants_t(config_t const &config = config_t()) noexcept :
20
+ fitness(0),
21
+ changed(true),
22
+ config(config),
23
+ questions(config.variants_count) {
24
+ }
25
+
26
+ variants_t(variants_t const &v) noexcept :
27
+ fitness(v.fitness),
28
+ changed(v.changed),
29
+ config(v.config),
30
+ questions(v.questions) {
31
+ }
32
+
33
+ variants_t(variants_t &&v) noexcept :
34
+ config(v.config) {
35
+ std::swap(fitness, v.fitness);
36
+ std::swap(changed, v.changed);
37
+ std::swap(questions, v.questions);
38
+ }
39
+
40
+ variants_t &operator = (variants_t &&v) noexcept {
41
+ std::swap(fitness, v.fitness);
42
+ std::swap(changed, v.changed);
43
+ std::swap(questions, v.questions);
44
+
45
+ return *this;
46
+ }
47
+
48
+ variants_t &operator = (variants_t const &v) noexcept {
49
+ fitness = v.fitness;
50
+ changed = v.changed;
51
+ questions = v.questions;
52
+
53
+ return *this;
54
+ }
55
+
56
+ void push_back(std::vector<question_t> const &q) noexcept {
57
+ questions.push_back(q);
58
+ }
59
+
60
+ size_t size() const noexcept {
61
+ return questions.size();
62
+ }
63
+
64
+ std::vector<std::vector<question_t>>::iterator begin() noexcept {
65
+ return questions.begin();
66
+ }
67
+
68
+ std::vector<std::vector<question_t>>::iterator end() noexcept {
69
+ return questions.end();
70
+ }
71
+
72
+ double calculate_fitness_function() const noexcept {
73
+ if (!changed)
74
+ return fitness;
75
+ size_t questions_count = 0;
76
+ for (auto const &v : questions)
77
+ questions_count += v.size();
78
+ {
79
+ size_t buffer[questions_count];
80
+ for (size_t i = 0; i < questions.size(); ++i)
81
+ for (size_t j = 0; j < questions[i].size(); ++j)
82
+ buffer[i * config.questions_count + j] = questions[i][j].get_question_id();
83
+ std::sort(buffer, buffer + questions_count);
84
+ size_t count = 1;
85
+ for (size_t i = 1; i < questions_count; ++i)
86
+ count += buffer[i] != buffer[i - 1];
87
+ fitness = double(count) / questions_count;
88
+ }
89
+ {
90
+ for (size_t i = 0; i < questions.size(); ++i) {
91
+ size_t buffer[questions[i].size()];
92
+ for (size_t j = 0; j < questions[i].size(); ++j)
93
+ buffer[j] = questions[i][j].get_question_id();
94
+ std::sort(buffer, buffer + questions[i].size());
95
+ size_t count = 1;
96
+ for (size_t j = 1; j < questions[i].size(); ++j)
97
+ count += buffer[j] != buffer[j - 1];
98
+ fitness += count == questions[i].size();
99
+ }
100
+ }
101
+ {
102
+ for (size_t i = 0; i < questions.size(); ++i) {
103
+ size_t buffer[questions[i].size()];
104
+ for (size_t j = 0; j < questions[i].size(); ++j)
105
+ buffer[j] = questions[i][j].get_select_id();
106
+ std::sort(buffer, buffer + questions[i].size());
107
+ size_t count = 1;
108
+ for (size_t j = 1; j < questions[i].size(); ++j)
109
+ count += buffer[j] != buffer[j - 1];
110
+ fitness += double(count) / questions[i].size();
111
+ }
112
+ }
113
+ {
114
+ double buffer[questions_count];
115
+ for (size_t i = 0; i < questions.size(); ++i)
116
+ for (size_t j = 0; j < questions[i].size(); ++j)
117
+ buffer[i * config.questions_count + j] = questions[i][j].get_difficulty();
118
+ double avg = 0;
119
+ for (size_t i = 0; i < questions_count; ++i)
120
+ avg += buffer[i];
121
+ avg /= questions_count;
122
+ double x = 0;
123
+ for (size_t i = 0; i < questions_count; ++i)
124
+ x += (buffer[i] - avg) * (buffer[i] - avg);
125
+ x /= questions_count;
126
+ x = sqrt(x);
127
+ fitness += x;
128
+ }
129
+ {
130
+ for (size_t i = 0; i < questions.size(); ++i) {
131
+ size_t buffer[questions[i].size()];
132
+ for (size_t j = 0; j < questions[i].size(); ++j)
133
+ buffer[j] = questions[i][j].get_select_id();
134
+ std::sort(buffer, buffer + questions[i].size());
135
+ size_t count = 1;
136
+ for (size_t j = 1; j < questions[i].size(); ++j)
137
+ count += buffer[j] != buffer[j - 1];
138
+ std::pair<size_t, size_t> counter[count];
139
+ ssize_t k = -1;
140
+ for (size_t j = 0; j < questions[i].size(); ++j) {
141
+ if (k == -1 || buffer[j] != counter[k].first) {
142
+ ++k;
143
+ counter[k].second = 0;
144
+ }
145
+ ++counter[k].second;
146
+ }
147
+ std::sort(counter, counter + count, [] (std::pair<size_t, size_t> const &a, std::pair<size_t, size_t> const &b) -> bool {
148
+ return a.second > b.second;
149
+ });
150
+ double x = 0;
151
+ for (size_t j = 1; j < count; ++j)
152
+ x += counter[j].second / counter[j - 1].second;
153
+ fitness += x;
154
+ }
155
+ }
156
+ changed = false;
157
+ return fitness;
158
+ }
159
+
160
+ variants_t crossover(variants_t const &v) const noexcept {
161
+ variants_t result(*this);
162
+ size_t questions_count = 0;
163
+ for (auto const &v : questions)
164
+ questions_count += v.size();
165
+ size_t to_swap = rand() % questions_count;
166
+ for (size_t i = 0; i < result.questions.size() && to_swap; ++i)
167
+ for (size_t j = 0; j < result.questions[i].size() && to_swap; ++j, --to_swap)
168
+ result.questions[i][j] = v.questions[i][j];
169
+ return result;
170
+ }
171
+
172
+ std::vector<question_t> &operator [] (size_t i) noexcept {
173
+ changed = true;
174
+ return questions[i];
175
+ }
176
+
177
+ std::vector<question_t> const &operator [] (size_t i) const noexcept {
178
+ return questions[i];
179
+ }
180
+
181
+ void strong_mutation(question_shaker_t const &shaker) noexcept {
182
+ for (std::vector<question_t> &q : *this) {
183
+ std::sort(q.begin(), q.end(), [] (question_t const &a, question_t const &b) -> bool {
184
+ return a.get_question_id() < b.get_question_id();
185
+ });
186
+ for (size_t i = 1; i < q.size(); ++i) {
187
+ if (q[i].get_question_id() == q[i - 1].get_question_id()) {
188
+ size_t r = rand() % config.topics.size();
189
+ q[i - 1] = shaker.get_question(config.topics[r]);
190
+ }
191
+ }
192
+ }
193
+ }
194
+
195
+ std::vector<std::vector<question_t>> const &get_questions() const noexcept {
196
+ return questions;
197
+ }
198
+ };
199
+
200
+ }
@@ -1,3 +1,3 @@
1
1
  module TasksGenerator
2
- VERSION = "0.5"
2
+ VERSION = "1.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tasks_generator
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.5'
4
+ version: '1.0'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arslan Urtashev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-04 00:00:00.000000000 Z
11
+ date: 2014-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -28,28 +28,28 @@ dependencies:
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ! '>='
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ! '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rice
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ! '>='
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ! '>='
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  description: Test Tasks Generator for AI lab MEPhI
@@ -67,13 +67,11 @@ files:
67
67
  - ext/tasks_generator/bindings.cc
68
68
  - ext/tasks_generator/config.h
69
69
  - ext/tasks_generator/extconf.rb
70
- - ext/tasks_generator/function.cc
71
- - ext/tasks_generator/function.h
72
- - ext/tasks_generator/generator.cc
73
70
  - ext/tasks_generator/generator.h
74
71
  - ext/tasks_generator/question.h
75
- - ext/tasks_generator/theme.h
76
- - ext/tasks_generator/types.h
72
+ - ext/tasks_generator/question_shaker.h
73
+ - ext/tasks_generator/topic.h
74
+ - ext/tasks_generator/variants.h
77
75
  - lib/tasks_generator.rb
78
76
  - lib/tasks_generator/version.rb
79
77
  - tasks_generator.gemspec
@@ -87,17 +85,17 @@ require_paths:
87
85
  - lib
88
86
  required_ruby_version: !ruby/object:Gem::Requirement
89
87
  requirements:
90
- - - '>='
88
+ - - ! '>='
91
89
  - !ruby/object:Gem::Version
92
90
  version: '0'
93
91
  required_rubygems_version: !ruby/object:Gem::Requirement
94
92
  requirements:
95
- - - '>='
93
+ - - ! '>='
96
94
  - !ruby/object:Gem::Version
97
95
  version: '0'
98
96
  requirements: []
99
97
  rubyforge_project:
100
- rubygems_version: 2.0.14
98
+ rubygems_version: 2.4.4
101
99
  signing_key:
102
100
  specification_version: 4
103
101
  summary: Test Tasks Generator
@@ -1,147 +0,0 @@
1
- #include <algorithm>
2
- #include <unordered_map>
3
- #include <unordered_set>
4
- #include <vector>
5
-
6
- #include <cassert>
7
- #include <cstdlib>
8
-
9
- #include "function.h"
10
- #include "question.h"
11
-
12
- namespace tasks_generator {
13
-
14
- population_t generate_population(config_t const &config, std::vector<question_t> const &questions) {
15
-
16
- std::unordered_map<theme_id_t, std::vector<question_t>> all_questions;
17
- for (question_t const &question : questions)
18
- all_questions[question.get_theme_id()].push_back(question);
19
- for (std::pair<theme_id_t const, std::vector<question_t>> &q : all_questions)
20
- std::sort(q.second.begin(), q.second.end(), question_t::difficulty_cmp);
21
-
22
- population_t population(config.population_size);
23
-
24
- srand((unsigned int)time(0));
25
-
26
- for (individual_t &individual : population) {
27
- individual = individual_t(config.tasks, task_t(config.themes.size()));
28
-
29
- for (task_t &task : individual) {
30
- task = task_t(config.themes.size());
31
-
32
- std::unordered_set<question_id_t> used;
33
-
34
- for (size_t i = 0; i < task.size(); ++i) {
35
- std::vector<question_t> const &candidates = all_questions[config.themes[i].get_theme_id()];
36
-
37
- std::vector<question_t>::const_iterator lower = std::lower_bound(
38
- candidates.begin(),
39
- candidates.end(),
40
- config.themes[i].get_difficulty_min(),
41
- question_t::difficulty_size_t_cmp
42
- );
43
-
44
- size_t unused_count = 0;
45
- std::vector<question_t>::const_iterator it = lower;
46
- while (it != candidates.end() && it->get_difficulty() <= config.themes[i].get_difficulty_max()) {
47
- if (used.find(it->get_question_id()) == used.end())
48
- ++unused_count;
49
- ++it;
50
- }
51
-
52
- if (unused_count == 0)
53
- throw std::logic_error("hasn't questions for generate test");
54
-
55
- size_t pos = rand() % unused_count;
56
-
57
- it = lower;
58
- while (pos > 0 || used.find(it->get_question_id()) != used.end()) {
59
- if (used.find(it->get_question_id()) == used.end())
60
- --pos;
61
- ++it;
62
- }
63
-
64
- task[i] = *it;
65
- used.insert(it->get_question_id());
66
- }
67
- }
68
- }
69
-
70
- return population;
71
- }
72
-
73
- static double fitness(individual_t const &individual) {
74
- double s = 0, sqrs = 0;
75
- for (task_t const &task : individual) {
76
- double avg = 0;
77
- for (question_t const &question : task)
78
- avg += question.get_difficulty();
79
- avg /= task.size();
80
- s += avg;
81
- sqrs += avg * avg;
82
- }
83
- double d = (sqrs - s * s / individual.size()) / individual.size();
84
- double metric_one = (d > 0 ? 1.0 / d + 1.0 : 2);
85
-
86
- std::unordered_set<size_t> uniqs;
87
- for (task_t const &task : individual)
88
- for (question_t const &question : task)
89
- uniqs.insert(question.get_question_id());
90
-
91
- return metric_one * uniqs.size(); // FIXME: add diff metric
92
- }
93
-
94
- static individual_t crossover(individual_t const &a, individual_t const &b) {
95
- // FIXME: change this crossover
96
- assert(a.size() == b.size());
97
- individual_t res;
98
- size_t to = rand() % a.size();
99
- for (size_t i = 0; i < to; ++i)
100
- res.push_back(a[i]);
101
- for (size_t i = to; i < b.size(); ++i)
102
- res.push_back(b[i]);
103
- return res;
104
- }
105
-
106
- static void sort_by_fitness(population_t &population) {
107
- std::vector<std::pair<double, size_t>> buf(population.size());
108
- for (size_t i = 0; i < population.size(); ++i) {
109
- buf[i].first = fitness(population[i]);
110
- buf[i].second = i;
111
- }
112
- std::sort(buf.begin(), buf.end());
113
- for (size_t i = 0; i < population.size(); ++i)
114
- std::swap(population[i], population[buf[i].second]);
115
- }
116
-
117
- individual_t best(population_t &population) {
118
- assert(!population.empty());
119
- sort_by_fitness(population);
120
- return population.front();
121
- }
122
-
123
- void selection(config_t const &config, population_t &population) {
124
- // FIXME: make selection better
125
- sort_by_fitness(population);
126
- population.resize(config.population_size);
127
- }
128
-
129
- void recombination(config_t const &config, population_t &population) {
130
- if (population.empty())
131
- throw std::logic_error("population is empty");
132
- std::vector<individual_t> newbies;
133
- for (size_t i = 0; i < population.size(); ++i) {
134
- size_t pos = i + rand() % (population.size() - i);
135
- std::swap(population[i], population[pos]);
136
- }
137
- for (size_t i = 0; i < population.size(); i += 2) {
138
- newbies.push_back(crossover(population[i], population[i + 1]));
139
- }
140
- for (size_t i = 0; i < newbies.size(); ++i)
141
- population.emplace_back(std::move(newbies[i]));
142
- }
143
-
144
- void mutation(config_t const &, population_t &) {
145
- }
146
-
147
- }
@@ -1,22 +0,0 @@
1
- #pragma once
2
-
3
- #include <algorithm>
4
- #include <vector>
5
-
6
- #include "config.h"
7
- #include "question.h"
8
- #include "types.h"
9
-
10
- namespace tasks_generator {
11
-
12
- population_t generate_population(config_t const &config, std::vector<question_t> const &questions);
13
-
14
- individual_t best(population_t &population);
15
-
16
- void selection(config_t const &config, population_t &population);
17
-
18
- void recombination(config_t const &config, population_t &population);
19
-
20
- void mutation(config_t const &config, population_t &population);
21
-
22
- }
@@ -1,23 +0,0 @@
1
- #include <vector>
2
-
3
- #include "generator.h"
4
-
5
- #include "function.h"
6
- #include "question.h"
7
- #include "types.h"
8
-
9
- namespace tasks_generator {
10
-
11
- generator_t::answer_t generator_t::generate() const {
12
- population_t population = generate_population(config, questions);
13
-
14
- for (size_t current_time = 0; current_time < config.life_time; ++current_time) {
15
- selection(config, population);
16
- recombination(config, population);
17
- mutation(config, population);
18
- }
19
-
20
- return best(population);
21
- }
22
-
23
- }
@@ -1,42 +0,0 @@
1
- #pragma once
2
-
3
- #include "question.h"
4
-
5
- namespace tasks_generator {
6
-
7
- class theme_t {
8
- size_t theme_id, difficulty_min, difficulty_max;
9
-
10
- public:
11
- theme_t(size_t tid, size_t dmin, size_t dmax) :
12
- theme_id(tid),
13
- difficulty_min(dmin),
14
- difficulty_max(dmax) {
15
- }
16
-
17
- theme_t(theme_t const &th) :
18
- theme_id(th.theme_id),
19
- difficulty_min(th.difficulty_min),
20
- difficulty_max(th.difficulty_max) {
21
- }
22
-
23
- size_t get_theme_id() const {
24
- return theme_id;
25
- }
26
-
27
- size_t get_difficulty_min() const {
28
- return difficulty_min;
29
- }
30
-
31
- size_t get_difficulty_max() const {
32
- return difficulty_max;
33
- }
34
-
35
- bool operator == (theme_t const &t) const {
36
- return theme_id == t.theme_id &&
37
- difficulty_min == t.difficulty_min &&
38
- difficulty_max == t.difficulty_max;
39
- }
40
- };
41
-
42
- }
@@ -1,18 +0,0 @@
1
- #pragma once
2
-
3
- #include <vector>
4
-
5
- #include "question.h"
6
-
7
- #define __unsed __attribute__((unused))
8
-
9
- namespace tasks_generator {
10
-
11
- typedef std::vector<question_t> task_t;
12
- typedef std::vector<task_t> individual_t;
13
- typedef std::vector<individual_t> population_t;
14
-
15
- typedef size_t theme_id_t;
16
- typedef size_t question_id_t;
17
-
18
- }