-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
194 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
name: build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
on [push] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
#!/usr/bin/env python3 | ||
|
||
""" | ||
Self-adaptive | ||
""" | ||
|
||
|
||
from .base import BaseIndividual, BaseChromosome | ||
from .population import HOFPopulation | ||
from .chromosome import FloatChromosome | ||
from .utils import random, choice_with_fitness | ||
|
||
def lim(r, e): | ||
e -= 0.0001 | ||
return 0 if r <= e else (r - e)**2 / (1 - e) | ||
|
||
|
||
class SSAPopulation(HOFPopulation): | ||
|
||
def transit(self, *args, **kwargs): | ||
"""Transitation of the states of population | ||
It is considered to be the standard flow of the Genetic Algorithm | ||
""" | ||
self.mate() | ||
self.mutate() | ||
self.doom() | ||
|
||
for individual in self.individuals: | ||
individual.age += 1 | ||
if self.is_crowd(): | ||
self.select(0.3) | ||
|
||
def doom(self): | ||
self.individuals = [individual for individual in self.individuals if not individual.is_dead()] | ||
|
||
def mate(self): | ||
self.rank() | ||
children = [] | ||
for individual, other in zip(self.individuals[:-1], self.individuals[1:]): | ||
if random() < min(individual.cross_prob, other.cross_prob): | ||
if self.match(individual, other): | ||
children.append(individual.cross(other)) | ||
self.add_individuals(children) | ||
|
||
@classmethod | ||
def match(cls, individual, other): | ||
if individual.label != other.label: | ||
a, b, c = lim(other.ranking, individual.expect), lim(individual.ranking, other.expect), abs(individual.age - other.age) | ||
p = 1 - c/(20*min(a, b)+1) | ||
return random() < p | ||
else: | ||
return random() < 0.05 | ||
|
||
def is_crowd(self): | ||
return len(self) > 8 * self.default_size | ||
|
||
def select(self, p=0.5): | ||
# self.select(n_sel=p) | ||
self.individuals = choice_with_fitness(self.individuals, fs=None, n=int(self.n_individuals*p)) | ||
# self.individuals = [individual for individual in self.individuals if random() < p] | ||
|
||
|
||
class SSAIndividual(BaseIndividual): | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
#!/usr/bin/env python3 | ||
|
||
import unittest | ||
|
||
from pyrimidine.individual import MonoIndividual | ||
from pyrimidine.population import HOFPopulation, BasePopulation | ||
from pyrimidine.chromosome import FloatChromosome | ||
from pyrimidine.de import DifferentialEvolution | ||
|
||
from pyrimidine.benchmarks.special import rosenbrock | ||
|
||
|
||
class TestDE(unittest.TestCase): | ||
|
||
def setUp(self): | ||
|
||
n = 20 | ||
f = rosenbrock | ||
|
||
class MyIndividual(MonoIndividual): | ||
element_class = FloatChromosome // n | ||
|
||
def _fitness(self): | ||
return -f(self.chromosome) | ||
|
||
class _Population1(DifferentialEvolution, BasePopulation): | ||
element_class = MyIndividual | ||
default_size = 10 | ||
|
||
class _Population2(HOFPopulation): | ||
element_class = MyIndividual | ||
default_size = 10 | ||
|
||
# _Population2 = HOFPopulation[MyIndividual] // 10 | ||
self.Population1 = _Population1 | ||
self.population1 = Population1.random() | ||
self.Population2 = _Population2 | ||
self.population2 = Population2.random() | ||
|
||
def test_clone(self): | ||
self.population2 = self.population1.clone(type_=self.Population2) # population 2 with the same initial values to population 1 | ||
assert isinstance(self.population2, self.Population2) | ||
|
||
def test_evolve(self): | ||
stat={'Mean Fitness':'mean_fitness', 'Best Fitness':'best_fitness'} | ||
data1 = self.population1.evolve(stat=stat, n_iter=10, history=True) | ||
data2 = self.population2.evolve(stat=stat, n_iter=10, history=True) | ||
assert True | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
#!/usr/bin/env python3 | ||
|
||
import unittest | ||
|
||
from pyrimidine import MonoIndividual, BinaryChromosome | ||
from pyrimidine import StandardPopulation, HOFPopulation | ||
from pyrimidine.benchmarks.optimization import * | ||
|
||
|
||
class TestGA(unittest.TestCase): | ||
|
||
def setUp(self): | ||
|
||
n_bags = 10 | ||
_evaluate = Knapsack.random(n_bags) | ||
|
||
class MyIndividual(MonoIndividual): | ||
|
||
element_class = BinaryChromosome.set(default_size=n_bags) | ||
|
||
def _fitness(self) -> float: | ||
return _evaluate(self.chromosome) | ||
|
||
class MyPopulation(StandardPopulation): | ||
element_class = MyIndividual | ||
default_size = 8 | ||
|
||
self.MyPopulation = MyPopulation | ||
|
||
class YourPopulation(HOFPopulation): | ||
element_class = MyIndividual | ||
default_size = 8 | ||
|
||
self.YourPopulation = YourPopulation | ||
self.population = self.MyPopulation.random() | ||
|
||
def test_random(self): | ||
self.population = self.MyPopulation.random() | ||
cpy = self.population.clone() | ||
self.population.merge(cpy, n_sel=8) | ||
assert len(self.population) == 16 | ||
|
||
def test_evolve(self): | ||
self.population.evolve(n_iter=2) | ||
assert True | ||
|
||
def test_stat(self): | ||
stat={'Mean Fitness':'mean_fitness', 'Best Fitness':'best_fitness'} | ||
data = self.population.evolve(stat=stat, n_iter=3, history=True) | ||
assert 'mean_fitness' in data.columns and 'best_fitness' in data.columns | ||
|
||
|
||
def test_hof(self): | ||
population = self.YourPopulation.random() | ||
|
||
stat={'Mean Fitness':'mean_fitness', 'Best Fitness':'best_fitness'} | ||
data = population.evolve(stat=stat, n_iter=5, history=True) | ||
|
||
def increasing(x): | ||
all(xi <= xj for xi, xj in zip(x[:-1], x[1:])) | ||
|
||
assert increasing(data['best_fitness']) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#!/usr/bin/env python3 | ||
|
||
import unittest | ||
|
||
from pyrimidine import IterativeModel | ||
|
||
|
||
class TestMeta(unittest.TestCase): | ||
|
||
def test_iteration(self): | ||
class TuringModel(IterativeModel): | ||
pass | ||
|
||
tm = TuringModel() | ||
assert True |