Skip to content

Commit 5c60d57

Browse files
committed
#44 remove_population_from/remove_population_to implemented in the sqlite_repository. cut_population(N) can me implemented by executing remove_population_from(N+1), remove_population_from(N-1), and removing the unused individuals
1 parent f72b73e commit 5c60d57

File tree

4 files changed

+180
-56
lines changed

4 files changed

+180
-56
lines changed

MLC/db/mlc_repository.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,6 @@ def add_population(self, population):
6161
def update_population(self, generation, population):
6262
raise NotImplementedError("This method must be implemented")
6363

64-
def remove_population(self, generation):
65-
raise NotImplementedError("This method must be implemented")
66-
6764
def get_population(self, generation):
6865
raise NotImplementedError("This method must be implemented")
6966

@@ -74,9 +71,6 @@ def count_population(self):
7471
def remove_population_from(self, from_generation):
7572
raise NotImplementedError("This method must be implemented")
7673

77-
def remove_last_population(self):
78-
raise NotImplementedError("This method must be implemented")
79-
8074
# operations over individuals
8175
def add_individual(self, individual):
8276
raise NotImplementedError("This method must be implemented")

MLC/db/sqlite/sql_statements.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ def stmt_delete_from_generations(from_generation):
2626
return """DELETE FROM population
2727
WHERE gen >= %s""" % (from_generation,)
2828

29+
def stmt_delete_to_generations(to_generation):
30+
return """DELETE FROM population
31+
WHERE gen <= %s""" % (to_generation,)
2932

3033
def stmt_delete_unused_individuals():
3134
return '''DELETE FROM individual

MLC/db/sqlite/sqlite_repository.py

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ def __init__(self, database, init_db=False):
2424
self.__execute(stmt_enable_foreign_key())
2525

2626
# cache for population
27-
self.__generations = self._how_many_generations()
27+
gen_numbers = self._get_generations()
28+
self.__generations = len(gen_numbers)
29+
self.__base_gen = gen_numbers[0] if gen_numbers else 1
2830

2931
# all individuals: {individual_id: (Individual, generated(bool))
3032
self.__individuals = self.__load_individuals()
@@ -77,13 +79,14 @@ def add_population(self, population):
7779
cursor = conn.cursor()
7880

7981
try:
82+
next_gen_id = self.__base_gen+self.__generations
8083
for i in range(len(population._individuals)):
8184
individual_id = population._individuals[i]
8285
individual_cost = population._costs[i]
8386
evaluation_time = population._ev_time[i]
8487
individual_gen_method = population._gen_method[i]
8588
individual_parents = ','.join(str(elem) for elem in population._parents[i])
86-
cursor.execute(stmt_insert_individual_in_population(self.__generations + 1,
89+
cursor.execute(stmt_insert_individual_in_population(next_gen_id,
8790
individual_id,
8891
individual_cost,
8992
evaluation_time,
@@ -97,25 +100,30 @@ def add_population(self, population):
97100

98101
self.__generations += 1
99102

100-
def remove_population(self, generation):
101-
self.__execute(stmt_delete_generation(generation))
102-
self.__generations -= 1
103-
104103
def get_population(self, generation):
105-
pop = self.__load_population(generation)
104+
gen_id = self.__base_gen + generation - 1
105+
pop = self.__load_population(gen_id)
106106
return pop
107107

108108
def count_population(self):
109109
return self.__generations
110110

111111
# special methods
112112
def remove_population_from(self, from_generation):
113-
self.__execute(stmt_delete_from_generations(from_generation))
113+
gen_id = self.__base_gen+from_generation-1
114+
self.__execute(stmt_delete_from_generations(gen_id))
114115
self.__generations = from_generation - 1
115-
116-
def remove_last_population(self):
117-
if self.__generations > 0:
118-
self.remove_population_from(self.__generations)
116+
if from_generation == 1:
117+
self.__base_gen = 1
118+
119+
def remove_population_to(self, to_generation):
120+
gen_id = self.__base_gen + to_generation - 1
121+
self.__execute(stmt_delete_to_generations(gen_id))
122+
self.__generations = self.__generations-to_generation
123+
if self.__generations == 0:
124+
self.__base_gen = 1
125+
else:
126+
self.__base_gen = to_generation + 1
119127

120128
def remove_unused_individuals(self):
121129
to_delete = []
@@ -232,15 +240,15 @@ def __execute(self, statement):
232240
conn.commit()
233241
return cursor.lastrowid
234242

235-
def _how_many_generations(self):
243+
def _get_generations(self):
236244
generations = []
237245
conn = self.__get_db_connection()
238246
cursor = conn.execute(stmt_get_generations())
239247
for row in cursor:
240248
generations.append(int(row[0]))
241249
cursor.close()
242250
conn.commit()
243-
return len(sorted(generations))
251+
return sorted(generations)
244252

245253
def __load_population(self, generation):
246254
i = 0

tests/mlc/db/test_mlc_repository.py

Lines changed: 155 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -315,13 +315,14 @@ def test_reload_individuals_from_file(self):
315315
self.assertEqual(mlc_repo.count_individual(), 2)
316316
self.assertEqual(mlc_repo.count_population(), 1)
317317

318-
def test_remove_last_population(self):
318+
def test_remove_from_population(self):
319319
mlc_repo = self.__get_new_repo()
320320

321321
# add individuals
322322
mlc_repo.add_individual(Individual("1+1"))
323323
mlc_repo.add_individual(Individual("2+2"))
324324
mlc_repo.add_individual(Individual("3+3"))
325+
mlc_repo.add_individual(Individual("4+4"))
325326

326327
# add first population
327328
p = Population(3, 0, Config.get_instance(), mlc_repo)
@@ -333,8 +334,13 @@ def test_remove_last_population(self):
333334
p._individuals = [1, 2, 3]
334335
mlc_repo.add_population(p)
335336

337+
# add third population
338+
p = Population(3, 0, Config.get_instance(), mlc_repo)
339+
p._individuals = [1, 2, 4]
340+
mlc_repo.add_population(p)
341+
336342
# remove last population
337-
mlc_repo.remove_last_population()
343+
mlc_repo.remove_population_from(2)
338344

339345
# last generation must be removed
340346
self.assertEqual(mlc_repo.count_population(), 1)
@@ -344,16 +350,11 @@ def test_remove_last_population(self):
344350
self.assertEqual(p._individuals, [1, 2, 1])
345351

346352
# all individuals exists and the third individual do not appear in any generation
347-
self.assertEqual(mlc_repo.count_individual(), 3)
348-
349-
data = mlc_repo.get_individual_data(3)
350-
self.assertEqual(data.get_value(), "3+3")
351-
self.assertEqual(data.get_appearances(), 0)
352-
self.assertEqual(data.get_cost_history(), {})
353+
self.assertEqual(mlc_repo.count_individual(), 4)
353354

354355
# remove unused individuals
355356
deleted = mlc_repo.remove_unused_individuals()
356-
self.assertEqual(deleted, 1)
357+
self.assertEqual(deleted, 2)
357358
self.assertEqual(mlc_repo.count_individual(), 2)
358359

359360
individual = mlc_repo.get_individual(1)
@@ -368,56 +369,174 @@ def test_remove_last_population(self):
368369
except KeyError:
369370
self.assertTrue(True)
370371

371-
def test_remove_from_population(self):
372+
def test_remove_population_to(self):
372373
mlc_repo = self.__get_new_repo()
373374

374375
# add individuals
375376
mlc_repo.add_individual(Individual("1+1"))
376377
mlc_repo.add_individual(Individual("2+2"))
377378
mlc_repo.add_individual(Individual("3+3"))
378379
mlc_repo.add_individual(Individual("4+4"))
380+
mlc_repo.add_individual(Individual("5+5"))
379381

380-
# add first population
382+
# add population
381383
p = Population(3, 0, Config.get_instance(), mlc_repo)
382-
p._individuals = [1, 2, 1]
384+
p._individuals = [1, 1, 1]
383385
mlc_repo.add_population(p)
384386

385-
# add second population
387+
# add population
386388
p = Population(3, 0, Config.get_instance(), mlc_repo)
387-
p._individuals = [1, 2, 3]
389+
p._individuals = [2, 2, 2]
388390
mlc_repo.add_population(p)
389391

390-
# add third population
392+
# add population
391393
p = Population(3, 0, Config.get_instance(), mlc_repo)
392-
p._individuals = [1, 2, 4]
394+
p._individuals = [3, 3, 3]
393395
mlc_repo.add_population(p)
394396

395-
# remove last population
396-
mlc_repo.remove_population_from(2)
397+
# add population
398+
p = Population(3, 0, Config.get_instance(), mlc_repo)
399+
p._individuals = [4, 4, 4]
400+
mlc_repo.add_population(p)
397401

398-
# last generation must be removed
399-
self.assertEqual(mlc_repo.count_population(), 1)
402+
self.assertEqual(mlc_repo.count_population(), 4)
403+
404+
# remove generations 1 to 2
405+
mlc_repo.remove_population_to(2)
406+
self.assertEqual(mlc_repo.count_population(), 2)
400407

401-
# first generation exists
402408
p = mlc_repo.get_population(1)
403-
self.assertEqual(p._individuals, [1, 2, 1])
409+
self.assertEqual(p._individuals, [3, 3, 3])
404410

405-
# all individuals exists and the third individual do not appear in any generation
406-
self.assertEqual(mlc_repo.count_individual(), 4)
411+
p = mlc_repo.get_population(2)
412+
self.assertEqual(p._individuals, [4, 4, 4])
413+
414+
# New generation must be number 3
415+
p = Population(3, 0, Config.get_instance(), mlc_repo)
416+
p._individuals = [5, 5, 5]
417+
mlc_repo.add_population(p)
418+
419+
self.assertEqual(mlc_repo.count_population(), 3)
420+
421+
p = mlc_repo.get_population(1)
422+
self.assertEqual(p._individuals, [3, 3, 3])
423+
424+
p = mlc_repo.get_population(2)
425+
self.assertEqual(p._individuals, [4, 4, 4])
426+
427+
p = mlc_repo.get_population(3)
428+
self.assertEqual(p._individuals, [5, 5, 5])
429+
430+
def test_remove_population_to_clear_generations(self):
431+
mlc_repo = self.__get_new_repo()
432+
433+
# add individuals
434+
mlc_repo.add_individual(Individual("1+1"))
435+
mlc_repo.add_individual(Individual("2+2"))
436+
mlc_repo.add_individual(Individual("3+3"))
437+
mlc_repo.add_individual(Individual("4+4"))
438+
mlc_repo.add_individual(Individual("5+5"))
439+
440+
# add population
441+
p = Population(3, 0, Config.get_instance(), mlc_repo)
442+
p._individuals = [1, 1, 1]
443+
mlc_repo.add_population(p)
444+
445+
# add population
446+
p = Population(3, 0, Config.get_instance(), mlc_repo)
447+
p._individuals = [2, 2, 2]
448+
mlc_repo.add_population(p)
449+
450+
# add population
451+
p = Population(3, 0, Config.get_instance(), mlc_repo)
452+
p._individuals = [3, 3, 3]
453+
mlc_repo.add_population(p)
454+
455+
self.assertEqual(mlc_repo.count_population(), 3)
456+
457+
# Remove all generations (1 to 3)
458+
mlc_repo.remove_population_to(3)
459+
self.assertEqual(mlc_repo.count_population(), 0)
460+
461+
# Insert populations again
462+
p = Population(3, 0, Config.get_instance(), mlc_repo)
463+
p._individuals = [3, 3, 3]
464+
mlc_repo.add_population(p)
465+
466+
# add population
467+
p = Population(3, 0, Config.get_instance(), mlc_repo)
468+
p._individuals = [4, 4, 4]
469+
mlc_repo.add_population(p)
470+
471+
# add population
472+
p = Population(3, 0, Config.get_instance(), mlc_repo)
473+
p._individuals = [5, 5, 5]
474+
mlc_repo.add_population(p)
475+
476+
self.assertEqual(mlc_repo.count_population(), 3)
477+
478+
p = mlc_repo.get_population(1)
479+
self.assertEqual(p._individuals, [3, 3, 3])
480+
481+
p = mlc_repo.get_population(2)
482+
self.assertEqual(p._individuals, [4, 4, 4])
483+
484+
p = mlc_repo.get_population(3)
485+
self.assertEqual(p._individuals, [5, 5, 5])
486+
487+
def test_cut_generation(self):
488+
"""
489+
Cut a generation using remove_population_from/remove_population_last
490+
:return:
491+
"""
492+
mlc_repo = self.__get_new_repo()
493+
494+
# add individuals
495+
mlc_repo.add_individual(Individual("1+1"))
496+
mlc_repo.add_individual(Individual("2+2"))
497+
mlc_repo.add_individual(Individual("3+3"))
498+
mlc_repo.add_individual(Individual("4+4"))
499+
mlc_repo.add_individual(Individual("5+5"))
500+
501+
# add population
502+
p = Population(3, 0, Config.get_instance(), mlc_repo)
503+
p._individuals = [1, 1, 1]
504+
mlc_repo.add_population(p)
505+
506+
# add population
507+
p = Population(3, 0, Config.get_instance(), mlc_repo)
508+
p._individuals = [2, 2, 2]
509+
mlc_repo.add_population(p)
510+
511+
# add population
512+
p = Population(3, 0, Config.get_instance(), mlc_repo)
513+
p._individuals = [3, 3, 3]
514+
mlc_repo.add_population(p)
515+
516+
# add population
517+
p = Population(3, 0, Config.get_instance(), mlc_repo)
518+
p._individuals = [4, 4, 4]
519+
mlc_repo.add_population(p)
520+
521+
# add population
522+
p = Population(3, 0, Config.get_instance(), mlc_repo)
523+
p._individuals = [5, 5, 5]
524+
mlc_repo.add_population(p)
525+
526+
self.assertEqual(mlc_repo.count_population(), 5)
527+
528+
# Cut population 4
529+
mlc_repo.remove_population_from(4+1)
530+
mlc_repo.remove_population_to(4-1)
407531

408532
# remove unused individuals
409-
deleted = mlc_repo.remove_unused_individuals()
410-
self.assertEqual(deleted, 2)
411-
self.assertEqual(mlc_repo.count_individual(), 2)
533+
mlc_repo.remove_unused_individuals()
412534

413-
individual = mlc_repo.get_individual(1)
414-
self.assertEqual(individual.get_value(), "1+1")
535+
self.assertEqual(mlc_repo.count_population(), 1)
536+
self.assertEqual(mlc_repo.count_individual(), 1)
415537

416-
individual = mlc_repo.get_individual(2)
417-
self.assertEqual(individual.get_value(), "2+2")
538+
p = mlc_repo.get_population(1)
539+
self.assertEqual(p._individuals, [4, 4, 4])
418540

419-
try:
420-
individual = mlc_repo.get_individual(3)
421-
self.assertTrue(False)
422-
except KeyError:
423-
self.assertTrue(True)
541+
individual = mlc_repo.get_individual(4)
542+
self.assertEqual(individual.get_value(), "4+4")

0 commit comments

Comments
 (0)