├── requirements.txt ├── README.rst ├── bas ├── __init__.py ├── rbas.py ├── bbas.py └── bas.py ├── demo ├── demo.py └── demo2.py ├── LICENSE ├── setup.py └── .gitignore /requirements.txt: -------------------------------------------------------------------------------- 1 | snowland-algorithm>=0.0.7 2 | numpy>=1.0.0 3 | astartool>=0.0.2 4 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | ===== 2 | pybas 3 | ===== 4 | 5 | Beetle Antennae Search Algorithm for python 3.x 6 | (based on snowland-algorithm) -------------------------------------------------------------------------------- /bas/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # @Author : 河北雪域网络科技有限公司 A.Star 4 | # @contact: astar@snowland.ltd 5 | # @site: www.snowland.ltd 6 | # @file: __init__.py.py 7 | # @time: 2018/8/28 10:36 8 | # @Software: PyCharm 9 | 10 | from bas.rbas import RBAS 11 | from bas.bas import BAS 12 | 13 | from astartool.setuptool import get_version 14 | 15 | version = (0, 0, 2, 'final', 0) 16 | __version__ = get_version(version) 17 | 18 | del get_version 19 | -------------------------------------------------------------------------------- /demo/demo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # @Author : 河北雪域网络科技有限公司 A.Star 4 | # @contact: astar@snowland.ltd 5 | # @site: www.snowland.ltd 6 | # @file: demo.py 7 | # @time: 2018/8/30 2:49 8 | # @Software: PyCharm 9 | 10 | from bas.rbas import RBAS 11 | 12 | 13 | from bas.rbas import RBAS 14 | import numpy as np 15 | 16 | 17 | # 使用前请安装文件 18 | # pip install pybas 19 | # 确保版本号大于0.0.1 20 | 21 | # 求 z = -cos(x) - sin(y)(x in [1, 2*pi], y in [1, 2*pi]) 的最大值 22 | 23 | def fun(vars): 24 | # 评价函数 25 | x, y = vars 26 | # if 0 <= x <= 2 * np.pi and 0 <= y <= 2 * np.pi: 27 | return -np.cos(x) - np.sin(y) + 10 28 | # else: 29 | # return -10 # 返回一个达不到的小值 30 | 31 | bas = RBAS(fitness_function=fun, dim=2) 32 | bas.run() 33 | print(bas.gbest) -------------------------------------------------------------------------------- /demo/demo2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # @Author: 河北雪域网络科技有限公司 A.Star 4 | # @contact: astar@snowland.ltd 5 | # @site: www.snowland.ltd 6 | # @file: demo2.py 7 | # @time: 2019/7/25 10:52 8 | # @Software: PyCharm 9 | 10 | 11 | __author__ = 'A.Star' 12 | 13 | from bas import BAS 14 | 15 | 16 | def f(x): 17 | c, d = x 18 | return 1 / ((1 + (c + d + 1) ** 2 * (19 - 14 * c + 3 * d ** 2 - 14 * d + 6 * c * d + 3 * d ** 2)) * ( 19 | 30 + (2 * c - 3 * d) ** 2 * (18 - 32 * c + 12 * c ** 2 + 48 * d - 36 * c * d + 27 * d ** 2))) 20 | 21 | 22 | if __name__ == '__main__': 23 | bas_engine = BAS( 24 | steps=500, 25 | dim=2, 26 | fitness_function=f, 27 | step=1, 28 | eta=0.95, 29 | bound=[[-2, 2], [-2, 2]], 30 | transboundary_rules='mod' 31 | ) 32 | bas_engine.run() 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, AAFun 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # @Time : 2018/3/5 0005 上午 1:29 4 | # @Author : 河北雪域网络科技有限公司 A.Star 5 | # @Site : 6 | # @File : setup.py 7 | # @Software: PyCharm 8 | 9 | # !/usr/bin/env python 10 | # coding=utf-8 11 | 12 | from setuptools import setup, find_packages 13 | import bas 14 | from astartool.setuptool import load_install_requires 15 | 16 | 17 | setup( 18 | name="pybas", 19 | version=bas.__version__, 20 | description=( 21 | 'Beetle Antennae Search Algorithm for python 3.x' 22 | ), 23 | long_description=open('README.rst').read(), 24 | author='A.Star', 25 | author_email='astar@snowland.ltd', 26 | maintainer='A.Star', 27 | maintainer_email='astar@snowland.ltd', 28 | license='BSD License', 29 | packages=find_packages(), 30 | platforms=["all"], 31 | url='', 32 | classifiers=[ 33 | 'Development Status :: 4 - Beta', 34 | 'Operating System :: OS Independent', 35 | 'Intended Audience :: Developers', 36 | 'License :: OSI Approved :: BSD License', 37 | 'Programming Language :: Python', 38 | 'Programming Language :: Python :: Implementation', 39 | 'Programming Language :: Python :: 2', 40 | 'Programming Language :: Python :: 2.7', 41 | 'Programming Language :: Python :: 3', 42 | 'Programming Language :: Python :: 3.4', 43 | 'Programming Language :: Python :: 3.5', 44 | 'Programming Language :: Python :: 3.6', 45 | 'Programming Language :: Python :: 3.7', 46 | 'Topic :: Software Development :: Libraries' 47 | ], 48 | install_requires=load_install_requires(), 49 | ) 50 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | -------------------------------------------------------------------------------- /bas/rbas.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # @Author : 河北雪域网络科技有限公司 A.Star 4 | # @contact: astar@snowland.ltd 5 | # @site: www.snowland.ltd 6 | # @file: rbas.py 7 | # @time: 2018/8/29 18:36 8 | # @Software: PyCharm 9 | 10 | 11 | from slapy.swarm.bas import BASEngine 12 | import numpy as np 13 | from copy import deepcopy 14 | 15 | npr = np.random 16 | 17 | 18 | 19 | # 模拟退火结合的BAS 20 | 21 | 22 | class RBASEngine(BASEngine): 23 | def __init__(self, steps=100, eps=0.01, chromosome=None, dim=2, bound=None, fitness_function=None, *, 24 | fitness_value=-np.inf, init_method='random', step0=1, c=5, eta=0.95, **kwargs): 25 | """ 26 | :param steps: 迭代次数 27 | :param eps: 精度 28 | :param chromosome: 数据值 29 | :param dim: 数据维度 30 | :param bound: 数据范围 31 | :param fitness_function: 评价函数 32 | :param fitness_value: 评价值 33 | :param init_method: 初始化参数 34 | :param step0: 初值 35 | :param c: 36 | :param eta: 37 | :param kwargs: 38 | """ 39 | super().__init__(steps, eps, chromosome, dim, bound, fitness_function, fitness_value=fitness_value, 40 | init_method=init_method, step0=step0, c=c, eta=eta, **kwargs) 41 | 42 | def update(self, *args, **kwargs): 43 | d0 = self.step / self.c 44 | dir = npr.rand(self.dim) - 1 45 | dir = dir / (self.eps + np.linalg.norm(dir)) 46 | xleft = self.chromosome + dir * d0 47 | fleft = self.fitness_function(xleft) 48 | xright = self.chromosome - dir * d0 49 | fright = self.fitness_function(xright) 50 | 51 | if self.fitness() > self.gbest.fitness_value: 52 | self.gbest = deepcopy(self) 53 | self.chromosome -= self.step * dir * np.sign(-fleft + fright) 54 | else: 55 | if npr.rand() < self.step: 56 | self.chromosome -= self.step * dir * np.sign(fleft - fright) 57 | else: 58 | self.chromosome -= self.step * dir * np.sign(-fleft + fright) 59 | 60 | self.step *= self.eta 61 | 62 | RBAS = RBASEngine -------------------------------------------------------------------------------- /bas/bbas.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # @Author : 河北雪域网络科技有限公司 A.Star 4 | # @contact: astar@snowland.ltd 5 | # @site: www.snowland.ltd 6 | # @file: bbas.py 7 | # @time: 2018/11/12 8:40 8 | # @Software: PyCharm 9 | 10 | from copy import deepcopy 11 | from slapy.swarm.bas import BASEngine 12 | import numpy as np 13 | 14 | npr = np.random 15 | 16 | 17 | class BBAS(BASEngine): 18 | def __init__(self, steps=100, eps=0.01, chromosome=None, dim=2, bound=None, fitness_function=None, *, 19 | fitness_value=-np.inf, init_method='random', step0=1, c=5, eta=0.95, **kwargs): 20 | """ 21 | 22 | :param steps: 迭代次数 23 | :param eps: 精度 24 | :param chromosome: 数据值 25 | :param dim: 数据维度 26 | :param bound: 数据范围 27 | :param fitness_function: 评价函数 28 | :param fitness_value: 评价值 29 | :param init_method: 初始化参数 30 | :param step0: 初值 31 | :param c: 32 | :param eta: 33 | :param kwargs: 34 | """ 35 | super().__init__(steps, eps, chromosome, dim, bound, fitness_function, fitness_value=fitness_value, 36 | init_method=init_method, step0=step0, c=c, eta=eta, **kwargs) 37 | raise FutureWarning('module will be supported in the future') 38 | 39 | def update(self, *args, **kwargs): 40 | d0 = self.step / self.c 41 | dir = npr.rand(self.dim) - 1 42 | dir = dir / (self.eps + np.linalg.norm(dir)) 43 | xleft = self.chromosome + dir * d0 44 | fleft = self.fitness_function(xleft) 45 | xright = self.chromosome - dir * d0 46 | fright = self.fitness_function(xright) 47 | 48 | if self.fitness() > self.gbest.fitness_value: 49 | self.gbest = deepcopy(self) 50 | self.chromosome -= self.step * dir * np.sign(-fleft + fright) 51 | else: 52 | if npr.rand() < self.step: 53 | self.chromosome -= self.step * dir * np.sign(fleft - fright) 54 | else: 55 | self.chromosome -= self.step * dir * np.sign(-fleft + fright) 56 | 57 | self.step *= self.eta 58 | -------------------------------------------------------------------------------- /bas/bas.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # @Author: 河北雪域网络科技有限公司 A.Star 4 | # @contact: astar@snowland.ltd 5 | # @site: www.snowland.ltd 6 | # @file: bas.py 7 | # @time: 2019/7/25 11:15 8 | # @Software: PyCharm 9 | 10 | 11 | __author__ = 'A.Star' 12 | 13 | from matplotlib import pylab as plt 14 | import numpy as np 15 | from copy import deepcopy 16 | from slapy.swarm.bas import BASEngine 17 | 18 | npa = np.array 19 | npr = np.random 20 | 21 | # 带边界处理的BAS 22 | 23 | 24 | class BAS(BASEngine): 25 | def __init__(self, steps=100, eps=0.01, chromosome=None, dim=2, bound=None, fitness_function=None, *, 26 | fitness_value=-np.inf, init_method='random', step0=1, c=5, eta=0.95, **kwargs): 27 | super().__init__(steps, eps, chromosome, dim, bound, fitness_function, fitness_value=fitness_value, 28 | init_method=init_method, **kwargs) 29 | self.eta = eta 30 | self.c = c 31 | self.step = step0 32 | 33 | def update(self, *args, **kwargs): 34 | d0 = self.step / self.c 35 | dir = npr.rand(self.dim) - 1 36 | dir = dir / (self.eps + np.linalg.norm(dir)) 37 | xleft = self.chromosome + dir * d0 38 | fleft = self.fitness_function(xleft) 39 | xright = self.chromosome - dir * d0 40 | fright = self.fitness_function(xright) 41 | self.chromosome -= self.step * dir * np.sign(-fleft + fright) 42 | # 边界处理规则 43 | self.transboundary() 44 | 45 | if self.fitness() > self.gbest.fitness_value: 46 | self.gbest = deepcopy(self) 47 | self.step *= self.eta 48 | 49 | def fitness(self, *args, **kwargs): 50 | return super(BASEngine, self).fitness(*args, **kwargs) 51 | 52 | def initialize(self, *args, **kwargs): 53 | super(BASEngine, self).initialize(*args, **kwargs) 54 | self.gbest = deepcopy(self) 55 | self.best = [] 56 | self.path = [] 57 | 58 | def analysis(self, *args, **kwargs): 59 | print('-' * 15) 60 | print("best:", self.best) 61 | print('-' * 15) 62 | print("path:", self.path) 63 | print('-' * 15) 64 | plt.figure(1) 65 | path = npa(self.path) 66 | plt.plot(path[:, 0], path[:, 1], 'r+-') 67 | plt.figure(2) 68 | plt.title('itor in each steps') 69 | plt.plot(self.best, 'r-', label='best') 70 | plt.xlabel("Iteration") 71 | plt.ylabel("function value") 72 | plt.show() 73 | print(self.gbest.chromosome) 74 | 75 | def record(self, *args, **kwargs): 76 | print(len(self.path)) 77 | self.path.append(deepcopy(self.chromosome)) 78 | self.best.append(self.fitness_value) 79 | --------------------------------------------------------------------------------