Skip to content
Snippets Groups Projects
Commit bcc431b1 authored by amraj's avatar amraj
Browse files

Make an evolution on package

parent 7861b279
Branches
No related tags found
No related merge requests found
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
logs/
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
/.idea/
import pandas as pd
from pyea.individual import Individual
from pyea.population import Population
from pyea.fitness import Jump
from pyea.mutation import MutationWithCounter
from pyea.mutation import MutationWithCounter, StaticMutation
import matplotlib.pylab as plt
from datetime import datetime
def ea(instance_size, instance_number, max_iteration, potential, mutation):
static_pop = Population()
for item in range(instance_number):
ind = Individual(size=instance_size, potential=potential, mutation=mutation)
static_pop.add_individual(ind)
for _ in range(max_iteration):
for ind in static_pop.individuals:
if ind.potential.is_optimum(ind):
break
ind.mutate()
return static_pop.average_progress()
data = ea(instance_number=1, instance_size=40,
max_iteration=10000000, potential=Jump(jump_size=3), mutation=MutationWithCounter())
return ind
plt.plot(list(data.keys()), list(data.values()))
plt.show()
pop = ea(instance_number=1, instance_size=20,
max_iteration=100000000000, potential=Jump(jump_size=8), mutation=MutationWithCounter())
\ No newline at end of file
......@@ -42,22 +42,21 @@ class Individual:
def mutate(self):
change_list = self.mutation.mutated_bits(self)
new_value = self.update_potential(change_list)
if new_value >= self.get_potential():
self.flip_bits(change_list, new_value)
self.mutation.success(self.get_potential(), new_value)
else:
self.change = False
self.create_history_record(change_list if self.change else [], 'mutation')
def flip_bits(self, change_list, new_value):
self.last_changed = self.age
self.change = True
if new_value > self.get_potential():
self.last_improved = self.age
self.change = True
self.potential_value = new_value
self.create_history_record(change_list if self.change else [], 'mutation')
for item in change_list:
self.value[item] = not self.value[item]
......@@ -72,20 +71,22 @@ class Individual:
def create_history_record(self, change_bits, change_type):
if not hasattr(self, 'history'):
self.history = []
self.history.append({
current_history = {
'timestamp': datetime.timestamp(datetime.now()),
'age': self.age,
'changed_bits': change_bits,
'type': change_type,
'potential': self.get_potential()
})
}
print(current_history)
self.history.append(current_history)
self.age = self.age + 1
def get_last_history(self):
return self.history[-1] if hasattr(self, 'history') else {}
def get_history(self):
return {str(self.uuid): self.history}
return self.history
def get_progress(self):
return {item['age']: item['potential'] for item in self.history}
import numpy as np
from datetime import datetime
class Mutation:
def __init__(self):
self.rate = 0.5
self.geometric = {}
def mutated_bits(self, individual):
return []
......@@ -13,6 +15,35 @@ class Mutation:
def success(self, old_value, new_value):
pass
def _next_geometric(self, p):
sample_size = 10000000
if not (p in self.geometric) or self.geometric[p]['index'] >= sample_size:
self.geometric[p] = {
'index': 0,
'values': np.random.geometric(p, sample_size)
}
index = self.geometric[p]['index']
ng = self.geometric[p]['values'][index]
self.geometric[p]['index'] = index + 1
return ng
def uniformlyrandom(self, n, p):
change_list = []
change = 0
cnt = 0
while change <= n:
cnt = cnt+1
# TODO: Tune 4*p*n ! It can be done with lots of data
next = self._next_geometric(p)
change = change + next
if change <= n:
change_list.append(int(change - 1))
else:
break
return change_list
class StaticMutation(Mutation):
def __init__(self, p):
......@@ -20,40 +51,44 @@ class StaticMutation(Mutation):
self.rate = p
def mutated_bits(self, individual):
change = np.random.geometric(p=self.rate, size=1)[0]
change_list = []
while change <= individual.get_size():
change_list.append(int(change - 1))
change = change + np.random.geometric(p=self.rate, size=1)[0]
change_list = self.uniformlyrandom(individual.get_size(), self.rate)
return change_list
class MutationWithCounter(Mutation):
def __init__(self):
super().__init__()
self.limits = {}
self.counter_limits = {}
self.cumulative_limit = {}
self.reset_rate()
def counter_limit(self, n, rate):
if len(self.limits) < rate:
if len(self.counter_limits) < rate:
nm = n/rate
self.limits[rate] = int(2 * np.log(n) * np.power((np.e*nm), rate))
return self.limits[rate]
self.counter_limits[rate] = int(2 * np.log(n) * np.power((np.e*nm), rate))
return self.counter_limits[rate]
def limit(self, n, m):
return sum([self.counter_limit(n, i) for i in range(1, m+1)])
if len(self.cumulative_limit) < m:
self.cumulative_limit[m] = sum([self.counter_limit(n, i) for i in range(1, m+1)])
return self.cumulative_limit[m]
def mutated_bits(self, individual):
a = datetime.now()
counter = individual.age - individual.last_improved
b = datetime.now()
limit = self.limit(individual.get_size(), self.rate)
if counter > limit:
self.rate = self.rate + 1
print(self.rate)
c = datetime.now()
mutation_probability = self.rate/individual.get_size()
change = np.random.geometric(p=mutation_probability, size=1)[0]
change_list = []
while change <= individual.get_size():
change_list.append(int(change - 1))
change = change + np.random.geometric(p=mutation_probability, size=1)[0]
d = datetime.now()
change_list = self.uniformlyrandom(individual.get_size(), mutation_probability)
e = datetime.now()
# print('mutation', b - a, c - b, d - c, e - d, 'total', e-a)
f = datetime.now()
# print(f-e)
return change_list
def reset_rate(self):
......
......@@ -2,15 +2,16 @@ from pyea.individual import Individual
import uuid
import json
import os
from settings import project_path
from pyea.settings import project_path
from collections import defaultdict
class Population:
individuals = list()
def __init__(self):
self.uuid = uuid.uuid4()
self.individuals = list()
def add_individual(self, individual: Individual):
self.individuals.append(individual)
......
from pyea.individual import Individual
from individual import Individual
from typing import List
......
File moved
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment