tasks_generator 0.5 → 1.0

Sign up to get free protection for your applications and to get access to all the features.
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
- }