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

Initial commit

parents
No related branches found
No related tags found
No related merge requests found
Showing
with 494 additions and 0 deletions
# 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/
\ No newline at end of file
# Default ignored files
/workspace.xml
\ No newline at end of file
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 2.7 (pyea)" project-jdk-type="Python SDK" />
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/pyea.iml" filepath="$PROJECT_DIR$/.idea/pyea.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PySciProjectComponent">
<option name="PY_SCI_VIEW" value="true" />
<option name="PY_SCI_VIEW_SUGGESTED" value="true" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PyDocumentationSettings">
<option name="renderExternalDocumentation" value="true" />
</component>
<component name="TestRunnerService">
<option name="PROJECT_TEST_RUNNER" value="Unittests" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
File added
File added
File added
File added
File added
from individual import Individual
from population import Population
from fitness import OneMax, Jump
from mutation import StaticMutation, MutationWithCounter
import matplotlib.pylab as plt
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())
plt.plot(list(data.keys()), list(data.values()))
plt.show()
import numpy as np
class Fitness:
def __init__(self):
pass
def default_value(self):
return 0
def get_potential(self, individual):
pass
def update_potential(self, individual, flip_bits):
pass
def is_optimum(self, individual):
return True
class OneMax(Fitness):
def __init__(self):
super().__init__()
def compute_potential(self, value):
return np.count_nonzero(value)
def get_potential(self, individual):
return self.compute_potential(individual.value)
def update_potential(self, individual, flip_bits):
diff = sum([-1 if individual.value[bit] else 1 for bit in flip_bits])
return self.get_potential(individual) + diff
def is_optimum(self, individual):
if individual.size == self.get_potential(individual):
return True
return False
class Jump(Fitness):
def __init__(self, jump_size):
super().__init__()
self.jump_size = jump_size
def default_value(self):
return self.jump_size
def _compute_potential(self, size, one_max):
if one_max == size or one_max < size - self.jump_size:
jump = one_max + self.jump_size
else:
jump = size - one_max
return jump
def compute_potential(self, value):
one_max = np.count_nonzero(value)
return self._compute_potential(len(value), one_max)
def get_potential(self, individual):
return self.compute_potential(individual.value)
def update_potential(self, individual, flip_bits):
diff = sum([-1 if individual.value[bit] else 1 for bit in flip_bits])
##TODO: We assumed that it is not on the depth region
one_max = individual.get_potential() - self.jump_size + diff
return self._compute_potential(len(individual.value), one_max)
def is_optimum(self, individual):
if individual.size + self.jump_size == self.get_potential(individual):
return True
return False
import numpy as np
import uuid
from datetime import datetime
class Individual:
def __init__(self, size: int, potential, mutation):
self.set_size(size)
self.value = np.zeros(self.size)
self.potential_value = potential.default_value()
self.mutation = mutation
self.change = True
self.potential = potential
self.uuid = uuid.uuid4()
self.age = 0
self.last_changed = 0
self.last_improved = 0
self.mutate()
def get_potential(self):
return self.potential_value
def get_last_changed(self):
return self.last_changed
def get_last_improved(self):
return self.last_improved
def is_new(self):
return self.change
def update_potential(self, change_list):
return self.potential.update_potential(self, change_list)
def set_size(self, size):
self.size = size
def get_size(self):
return self.size
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
if new_value > self.get_potential():
self.last_improved = self.age
self.change = True
self.potential_value = new_value
for item in change_list:
self.value[item] = not self.value[item]
def __str__(self):
return " ".join(["1" if item else "0" for item in self.value])
def info(self):
return '''
-- size={number_of_bits} | Potential = {potential} | age = {age}
'''.format(number_of_bits=self.size, potential=self.potential(), age=len(self.history))
def create_history_record(self, change_bits, change_type):
if not hasattr(self, 'history'):
self.history = []
self.history.append({
'timestamp': datetime.timestamp(datetime.now()),
'age': self.age,
'changed_bits': change_bits,
'type': change_type,
'potential': self.get_potential()
})
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}
def get_progress(self):
return {item['age']: item['potential'] for item in self.history}
This diff is collapsed.
import numpy as np
class Mutation:
def __init__(self):
self.rate = 0.5
def mutated_bits(self, individual):
return []
def current_rate(self):
return self.rate
def success(self, old_value, new_value):
pass
class StaticMutation(Mutation):
def __init__(self, p):
super().__init__()
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]
return change_list
class MutationWithCounter(Mutation):
def __init__(self):
super().__init__()
self.limits = {}
self.reset_rate()
def counter_limit(self, n, rate):
if len(self.limits) < rate:
nm = n/rate
self.limits[rate] = int(2 * np.log(n) * np.power((np.e*nm), rate))
return self.limits[rate]
def limit(self, n, m):
return sum([self.counter_limit(n, i) for i in range(1, m+1)])
def mutated_bits(self, individual):
counter = individual.age - individual.last_improved
limit = self.limit(individual.get_size(), self.rate)
if counter > limit:
self.rate = self.rate + 1
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]
return change_list
def reset_rate(self):
self.rate = 1
def success(self, old_value, new_value):
if new_value > old_value:
self.reset_rate()
\ No newline at end of file
from individual import Individual
from typing import List
import uuid
import json
import os
from settings import project_path
from collections import defaultdict
class Population:
individuals = list()
def __init__(self):
self.uuid = uuid.uuid4()
def add_individual(self, individual: Individual):
self.individuals.append(individual)
def get_individual_number(self):
return len(self.individuals)
def export_data(self):
data = [ item.get_history() for item in self.individuals]
logs_path = project_path + '/logs'
if not os.path.exists(logs_path):
os.makedirs(logs_path)
with open(logs_path + '/data.json', 'w') as outfile:
json.dump(data, outfile)
def info(self):
return '''
-- population={number_of_inds}
'''.format(number_of_inds=self.get_individual_number())
def individuals_progress(self):
if not self.get_individual_number():
return None
data = defaultdict(list)
for ind in self.individuals:
for age, value in ind.get_progress().items():
data[age].append(value)
return data
def average_progress(self):
data = defaultdict(list)
progress = self.individuals_progress()
for age, value in progress.items():
data[age] = sum(value)/len(value)
return data
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment